Code Smell 106 - Production Dependent Code
Tags: webdev, cleancode, oop, tutorial
Published: 2021-11-27 15:36:13

*Don't add IFs checking for production environment.*

> TL;DR: Avoid adding conditionals related to production 

# Problems

- Fail fast principle violation

- Lack of testability

# Solutions

1. If completely necessary, model environments and test *ALL* of them.

# Context

Sometimes, We need to create different behaviors in development and production.

For example the passwords strength.

In this case, we need to configure the environment with the strength strategy and test the strategy and not the environment itself.

# Sample Code

## Wrong

[Gist Url]: # (https://gist.github.com/mcsee/2b00edcf1fded330263a4773b227cd06)
```python
def send_welcome_email(email_address, environment):
  if ENVIRONMENT_NAME == "production":
    print(f"Sending welcome email to {email_address} from Bob Builder <bob@builder.com>")
  else:
    print("Emails are sent only on production")
    
send_welcome_email("john@doe.com", "development")
# Emails are sent only on production

send_welcome_email("john@doe.com", "production")
# Sending welcome email to john@doe.com from Bob Builder <bob@builder.com>
```

## Right

[Gist Url]: # (https://gist.github.com/mcsee/4a598f416f01357597a072d75ba30a6f)
```python
class ProductionEnvironment:
  FROM_EMAIL = "Bob Builder <bob@builder.com>"

class DevelopmentEnvironment:
  FROM_EMAIL = "Bob Builder Development <bob@builder.com>"
  
#We can unit test environments
#and even implement different sending mechanisms

def send_welcome_email(email_address, environment):
  print(f"Sending welcome email to {email_address} from {environment.FROM_EMAIL}")
  #We can delegate into a fake sender (and possible logger)
  #and unit test it

send_welcome_email("john@doe.com", DevelopmentEnvironment())
# Sending welcome email to john@doe.com from Bob Builder Development <bob@builder.com>

send_welcome_email("john@doe.com", ProductionEnvironment())
# Sending welcome email to john@doe.com from Bob Builder <bob@builder.com>
```

# Detection

[X] Manual

This is a design smell. 

We need to create empty development/production configurations and delegate with customizable polymorphic objects.

# Tags

- Coupling

# Conclusion

Avoid adding untestable conditionals. 

Create configurations delegating business rules.

Use abstractions, protocol and interfaces, avoid hard hierarchies.

# Relations

{% post https://dev.to/mcsee/code-smell-56-preprocessors-4hf9 %}

# More Info

- [How to avoid annoying ifs](https://dev.to/mcsee/how-to-get-rid-of-annoying-ifs-forever-1jfg)

# Credits

Photo by <a href="https://unsplash.com/@birminghammuseumstrust">Birmingham Museums Trust</a> on <a href="https://unsplash.com/s/photos/production-line">Unsplash</a>
  
This tweet was inspired by @jangiacomelli 

{% twitter 1462469614177173505 %}

* * *

> Complexity is a sign of technical immaturity. Simplicity of use is the real sign of a well design product whether it is an ATM or a Patriot missile.

_Daniel T. Ling_
 
{% post https://dev.to/mcsee/software-engineering-great-quotes-26ci %}

* * *

This article is part of the CodeSmell Series.

{% post https://dev.to/mcsee/how-to-find-the-stinky-parts-of-your-code-1dbc %}