seagatewholesale.com

Understanding Primitive Obsession and Its Impact on Your Code

Written on

Chapter 1: The Hidden Dangers of Primitive Obsession

In virtually every codebase, there exists a pattern that, when left unchecked, complicates comprehension and exposes your domain model to vulnerabilities. This phenomenon is known as "primitive obsession."

Consider this: Do you find yourself reading more code than you actually write? For many developers, the answer is yes. Understanding someone else's code can be a true measure of its quality and design.

Primitive types, while common, often lead to several issues:

  1. They obscure the actual requirements of your code.
  2. They increase the likelihood of violating the DRY (Don't Repeat Yourself) principle.

The following code snippet illustrates some of these concerns:

class MediumMember:

def __init__(self, mail: str):

self.mail = self.validate_email(mail)

@staticmethod

def validate_email(mail: str) -> str:

# Validate the email format with RegEx

pass

The MediumMember class requires a valid email address, represented as a primitive string. While the constructor demands a string input, it fails to communicate the necessary validation checks, leaving the reader with little context. The name of the parameter, mail, offers limited insight, and any mistakes might only surface during execution, resulting in an exception.

Section 1.1: The Problem of Duplicated Logic

Another significant drawback appears when a second class requires similar email validation logic.

class GoldMember:

def __init__(self, mail: str):

self.mail = self.validate_email(mail)

@staticmethod

def validate_email(mail: str) -> str:

# Duplicate email validation logic

pass

At first glance, the GoldMember class seems fine; however, it also requires the email to be validated, leading to the dreaded duplication of logic.

You might think of refactoring this into a separate EmailServices class, but that would not be an ideal solution.

Section 1.2: The Consequences of Primitive Obsession

The obsession with using primitive types results in several negative outcomes:

  • The true requirements of the code remain unclear.
  • The risk of violating the DRY principle increases, as validation logic may be repeated across multiple classes.

Chapter 2: Solutions to Primitive Obsession

Eliminating primitive obsession necessitates encapsulating validation logic within dedicated classes.

Instead of relying on a primitive string, you can create an Email class with a private constructor. This will require the use of a static factory function to instantiate the object, centralizing the validation of the email string.

class Email:

def __init__(self, mail: str):

self.mail = mail

@staticmethod

def create(mail: str) -> 'Email':

# Central email validation logic

pass

When creating a GoldMember, you can now use:

gold_member = GoldMember(Email.create("[email protected]"))

This approach allows you to replace the primitive type String with a complex Email type, enhancing the clarity and quality of your code.

To better understand how to map domain concepts into classes rather than relying on primitive types, consider reading “Domain-Driven Design: Tackling Complexity in the Heart of Software.”

Using Implicit and Explicit Operators

To facilitate the assignment of complex types to primitive types, you can implement implicit operators. This allows you to directly assign an Email object to a string.

class Email:

...

def __str__(self):

return self.mail

Additionally, an explicit operator can be created to convert a string into an Email object, ensuring that both directions of assignment are seamless.

@classmethod

def from_string(cls, mail: str) -> 'Email':

return cls(mail)

By adhering to these principles, you can create a robust codebase.

To further your development journey, explore eight enduring guidelines designed to help you succeed in coding and advance in your career.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Exploring the Dark Side of Alien Encounters and Humanity

Delving into the complex relationship between aliens and humans, exploring the dark aspects and the philosophical implications of our existence.

Exploring the Concept of Music Addiction: A Deep Dive

A thorough examination of music addiction, its implications, and personal experiences.

Lessons from the San Francisco 49ers: Business Insights from Sports

Discover valuable business lessons inspired by the San Francisco 49ers and Bill Walsh's leadership philosophy.