Don’t be obsessed with design patterns

Designs can be a powerful assistant when we use them correctly.

However, when used incorrectly, the benefits are not good. The urgent thing is how we use them correctly.

Because a design is a solution that is predefined for a specific problem, tested over time, and known in the software community , you may want to apply it as soon as you have the opportunity. .

When you learn a new technology, it's good to try it right away. However, the concept of "finding the smallest opportunity to put designs into code" seems to be a bad idea for me.

How do I know when it is best to use the design? We will see below, assessing the possibility of changes in different parts of the source code and understanding the purpose of the design that we are using is important to make appropriate decisions.

I came to this conclusion by looking at the following three things. Let's point through them.

If you know and apply object-oriented design principles, the designs will come naturally.

I believe that knowing the principles of object-oriented design and applying principles like SOLID , KISS and YAGNI is much more important than the design itself. If you apply these principles, the designs will come naturally .

Let's consider an example. Suppose we are making a small application about exporting a track to the screen. Now, to streamline the problem, we only need to draw the white and black notes.

Among the different classes of the system, we have the following class:

cover

As you can see, there is clearly a overlap here. The only difference is the input parameter of the drawNoteHead function.

After reviewing, perhaps you come to the conclusion to eliminate the duplication we will do as follows:

1- Create a generic drawNote method and the function body is copied from either of the above functions.

2 – The input parameter of the drawNoteHead method will be taken by a new method. And, the source code of this new method can be written by subclasses, so the parent class retains the basic logic and the subclasses still keep the differences.

3 – Replace all calling methods to drawHalfNote and drawQuaterNote with the drawNote method of separate subclasses.

Okay, let's shake hands:

cover

There may be other solutions, but we have achieved what we want: eliminate source code duplication.

Guess what.

You have just applied the Template design template.

Just like that. No need to think. That is the good point of the object-oriented design principles.

You may not know all the designs, but as long as you understand object-oriented design principles, you don't need to know what to do.

Of course, if you already understand the Template design, you can see it immediately. You will say "it is perfect for applying a Template design template". The right way to apply the designs is: when you see it clearly, they fit and they make your work easier.

This leads me to the second point of view.

You may not need it

Sometimes when we look at a piece of code, we shudder at its ugliness, and we realize immediately that we need to apply a design pattern to make it better.

But what happens when it's working well and you don't need to change it?

For example, let's go back to the program to publish music to the screen, but with a slightly different scenario. Imagine that we want to create a class for each type of music course. Our application will support all music courses based on 3 primary keys: lock C, lock F and G.

We have a function that returns the correct music key we want. It looks like this:

cover

It is an ugly source code. Maybe you want to improve (refactor) it, right? Perhaps you are thinking of applying the Factory Method model, yes, it will fit and will definitely make your code cleaner.

But what if I tell you that this source code will never change?

I am not a musician, so I may be wrong, but it seems unrealistic to think that there will be new notes to be invented in the future. So if no notes are added, there is no need to change the source code above. No matter how ugly the source code is, if it works well you don't need to change it, refactoring the source code (with a design or any technique) will cost you unnecessary fees.

This leads me to the third point of view.

Cost for applying designs

There are many different designs, but most of them have in common: when you apply them, you need to set up a few structures. In other words, you need to add some classes or interfaces or both to the source code.

In the first example, this structure consists of an abstract class inherited by two subclasses. Furthermore, in order for the old source code to use these new classes, you also need to make some changes that are not directly related to the design itself.

The lesson to be learned is: if you are thinking about applying a design, consider the implementation costs and potential benefits. Just making it available will make your code more complex.

How can I know when is the best to use a design pattern?

That's a million dollar question. It depends on two things: how the source code will change in the future and the purpose of the design.

Ability to change in different parts of the source code.

The examples in this article introduce the importance of considering changes to decide whether or not to apply a design.

In the first example, applying the design completely is necessary. Because, we don't just publish music, but only with white notes and black notes, right? Because adding some more notes will make the problem worse, then a model is needed to avoid that.

In example two, it's the exact opposite. Because we can guarantee 100% that no music or notes are added, the code does not need to change and therefore, there is no need to apply the design.

Purpose of the model

It is not enough to only know how the design is implemented; but we also need to know the reason behind its existence.

In other words: we need to know what the model is created for.

We need to understand thoroughly the type of problem that the design pattern addresses. As such, we will easily know when is the right time to apply it.

When I made these kinds of decisions, I remembered two books:

Head First Design Patterns : if you have never heard of previous designs, or you are just beginning to learn, this book is really necessary. It explains the designs that are most often used in a very intuitive and understandable way.

Design Patterns: Elements of Reusable Object-Oriented Software : this is a classic book that you need to read. It is written as a summary of the most popular designs, organized into three main categories: initialization, initialization, and behavior.

Unfortunately, there is another problem we face: recognizing and applying models in projects.

When you write new code from scratch, it is quite easy to recognize the need for a design template. However, it is more difficult to apply the design to the old code.

Make sure you understand how the source code works before touching it. This can be easy or painful, depending on the complexity of the code.

Fortunately for us, there is another book that can help with this: Refactoring to Patterns . This book shows you how to really integrate the design into existing source code.

The books above, along with many other books, are on John's list of books and programming that I recommend reading.

Conclude

The designs are not the "holy grail" of programming. In fact I don't think such a thing exists.

They are simply mechanisms to make our code more clear and easier to understand and maintain … when applied correctly.

Written by Le Minh Thien

If you would like to share the article for Techtalk please send it to contact@techtalk.vn

Share the news now