Code Smell 106 - Production Dependent Code

Maxi Contieri - Nov 27 '21 - - Dev Community

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

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>
Enter fullscreen mode Exit fullscreen mode

Right

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>
Enter fullscreen mode Exit fullscreen mode

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

More Info

Credits

Photo by Birmingham Museums Trust on Unsplash

This tweet was inspired by @jangiacomelli


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


This article is part of the CodeSmell Series.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .