Back to Home

Overview Of Design Pattern

What is a Design Pattern?

Design patterns are standard solutions to common problems in software design. Much like a cooking recipe that outlines ingredients and steps to achieve a particular dish, a design pattern provides a proven approach to solving a specific problem, though the exact implementation may vary depending on the context (Refactoring.Guru). The fundamental idea is to leverage the experience and solutions developed by others to address recurring issues efficiently.

Design patterns are classified into three main categories:

Why Use Design Patterns?

The primary reasons for utilizing design patterns in software development are:

When to Use Design Patterns?

The decision to use a design pattern should be made judiciously. As noted by MoreSaltMoreLemon (2021), it’s often better to develop the code incrementally and adopt a design pattern as the complexity of the project increases. This gradual approach ensures that the design pattern fits naturally into the architecture rather than being forced prematurely.

Implementation Example

One of the design patterns popular in Odoo is the 2-step pattern, as mentioned in this talk by @gurneyalex. Here’s an example from the POS Product Label module, an OCA module in Odoo:

def prepare_product_label_layout_data(self, data):
    vals = {
        "product_ids": [Command.set(data["product_ids"])],
        "custom_quantity": data["custom_quantity"],
        "print_format": data["print_format"],
        "extra_html": (
            plaintext2html(data["extra_html"]) if data.get("extra_html") else False
        ),
    }
    return vals

def print_product_labels(self, data):
    """Print product labels from the POS.

    :param data: dict with the following keys:
        - pos_quantity: either 'order' or 'custom'
        - order_quantity_by_product: dict of {product_id: quantity}
        - product_ids: list of product ids
        - custom_quantity: int
        - print_format: str
        - extra_html: str
    """
    vals = self.prepare_product_label_layout_data(data)
    wizard = self.env["product.label.layout"].create(vals)
    if data.get("pos_quantity") == "order":
        wizard = wizard.with_context(
            force_label_qty_by_product=data.get("order_quantity_by_product", {})
        )
    return wizard.process()

As shown, print_product_labels focuses on using the prepared data for wizard processing, while prepare_product_label_layout_data handles the data preparation. This separation improves code readability and maintenance by clearly defining each method’s responsibility.

What is an Anti-Pattern?

An anti-pattern is essentially the opposite of a design pattern. It is a common response to a recurring problem that is ineffective and counterproductive. Recognizing and avoiding anti-patterns is crucial for maintaining code quality and ensuring the success of a project.

Conclusion

Design patterns are invaluable tools in software development, offering efficient solutions to common problems, enhancing problem-solving skills, and facilitating better communication among developers. However, they should be used thoughtfully and adapted to the specific needs of the project. Understanding and applying design patterns, while avoiding anti-patterns, can lead to the creation of more maintainable, scalable, and robust software.

References

Refactoring.Guru. What is a Design Pattern?

MoreSaltMoreLemon. (2021). Should I use a design pattern?

Odoo. (2022). Patterns and antipatterns in Odoo module development

© 2024 Tris Doan   •  Theme  Moonwalk