Skip to main content

Command Palette

Search for a command to run...

Code Smell 106 - Production Dependent Code

Published
2 min read
Code Smell 106 - Production Dependent Code

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>

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>

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 Jan Giacomelli


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.

Code Smells

Part 1 of 50

In this series, we will see several symptoms and situations that make us doubt the quality of our developments. We will present possible solutions. Most are just clues. They are no hard rules.

Code Smell 106 - Production Dependent Code