Design Patterns Overview

Design Patterns Overview

Welcome to my article, Design Patterns Overview. Design patterns have fascinated me for years. They’re like personal tools you can add to your toolkit as a software developer. They don’t take long to introduce, but they can take much practice to master. This article will explore the concept of design patterns, which you should start learning if you haven’t already. Some of the major topics we will cover include design patterns and where they come from. Why should you spend time teaching them? How should you approach this critical topic? And what are some good patterns to start with? By the end of this article, you’ll understand how design patterns can help you be a more effective software developer and have a proven strategy for learning more about them. I hope we can learn together by joining me on this journey!

Introducing Design Patterns

This article offers an introduction and overview of design patterns, a topic every software developer should strive to understand. By the end of this article, you’ll realize what design patterns are, how they’re discovered and defined, and why learning them is so important. In this article, you’re going to learn about the topic of design patterns. We’ll examine what they are, where they come from, and why you should bother to know them. Then we’ll look at some good ways to approach learning patterns since there are quite a few, with many different approaches you might take.

In this article, I’ll show you when it makes sense to apply patterns, since it’s common for developers new to patterns to be overzealous in their applications. I’ll also introduce a few common design patterns and show how they can be combined. According to Wikipedia, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context.

Design Pattern Origins

But let’s start at the beginning. Where did design patterns come from? In 1977, architect Christopher Alexander introduced the concept of design patterns in his book A Pattern Language: Towns, Buildings, Construction. In 1987, developers Ward Cunningham and Kent Beck were impressed by the results of their client project and presented their findings at the OOPSLA conference in Orlando. Then in 1991, Erich Gamma wrote a Ph.D. thesis on patterns, which would later lead to his developing the Design Patterns book with three co-authors. A Pattern Language: Towns, Buildings, Construction was written by Alexander in 1977.

No alt text provided for this image

This is the first book to identify the concept of design patterns. It documented 253 different patterns in the context of cities, towns, and buildings. The book defined a way to describe patterns. It organized them into other groups based on characteristics and provided an extensive catalog of patterns about towns and their structures. Design Patterns was published in 1994; strangely enough, it was given copyright in 1995. The book established a language for describing object-oriented software design patterns. It also organized these patterns by type: creational, structural, and behavioral styles were included in this book’s catalog of 23 individual design patterns. Since then, dozens of patterns have been identified and documented across many aspects of software development.

Why Learn Design Patterns?

Why would you want to learn design patterns? Don’t architects and college professors use them? I’m glad you asked. There are good reasons to learn about design patterns. It’s essential to understand how to avoid reinventing the wheel. Many problems you’ll face in your career have already been solved, and many patterns address them.

No alt text provided for this image

Second, patterns come with names and associated constructs that communicate more clearly. Knowing the patterns used by your team can help you communicate more effectively with them. Thirdly, patterns can help you to be more effective and to deliver better software. Complex problems or duplicate code implementations can often be solved elegantly using a design pattern. Knowing this, and even knowing to look for a pattern if you don’t remember one offhand, can dramatically improve your ability to ship quality software. And all of these things will help you improve and grow in your career.

A senior developer, or architect, should be familiar with the concept of design patterns. This familiarity can help you in your career. To illustrate how design patterns can help with communication, consider these two variations of a conversation that might occur between two team members during a code review. In one version, the conversation goes like this: “We have some tight coupling to the database here. We can probably fix it if we apply some refactorings.” Maybe we can start by extracting an interface to extend our design pattern knowledge to include the database layer. Then, we could remove a method that contains only persistence code and put it into its class that implements the interface we just created. And then we should be able to replace all the local instantiation of that class with a parameter that we can pass in and assign to a field.

No alt text provided for this image

Let’s look at that one little review comment with patterns. We have some tight coupling to the database here. Why don’t we use the repository pattern to eliminate it? Using a pattern name well understood by everyone involved makes communicating design intentions faster and more precise. I’m talking about this when I say knowing design patterns helps improve team communication.

How Should We Learn Design Patterns?

So, how can we learn design patterns? Should we just read about them or watch presentations like this one? Maybe you should memorize all their names. Everyone knows differently, but I have some recommendations for how you can learn design patterns most effectively to improve your code and your career. In my own experience with patterns and other areas like sports and martial arts—where there are distinct learning stages—I found distinct phases of learning. The first phase is ignorance; you don’t know that a concept, technique, or pattern exists. This is where everyone begins, but it’s also the most accessible phase from which to progress.

No alt text provided for this image

The next stage is what I call awakening. In this stage, you become aware of the thing about which you want to learn. You might say, “Wow, I just learned that XYZ pattern could help my design.” But then it becomes clear that you’re not sure how to apply it, but you’re keen to find out. This is where experimentation and some of the actual learning take place. Knowing there’s a pattern others have found helpful, you may try to use it everywhere you can. Generally, it’s less painful to practice new techniques in a controlled environment than in production or game day.

Eventually, with enough practice, you’ll learn where the pattern fits and where it doesn’t until, finally, you reach the final stage. This stage requires you to apply the pattern in various contexts. You can’t expect to master a pattern you’ve never actually used. However, with mastery, the final stage of learning, you’ve internalized the skill or pattern. You’ve developed muscle memory for applying it that no longer requires you to break down the steps and consciously go through them.

A standard recommendation when considering knowledge or skills is to be T-shaped: have a broad understanding of general concepts and a deep practical understanding of a few specific things. It’s generally less helpful to have vague, encyclopedia-like knowledge of a wide array of topics but no ability to deliver anything valuable using this knowledge. It’s also not ideal to only have a deep understanding and mastery of a minimal number of tools or techniques without understanding other ways to approach things.

You risk being a one-trick pony with a golden hammer that you apply to every problem. You can apply the concept of T-shaped knowledge to design patterns as well. If someone mentions that they want to use the observer or flyweight to tackle a problem, you should immediately recognize that they’re referring to a specific pattern. It’s okay if you don’t know that pattern intimately, but your broad knowledge of patterns should let you participate in any discussion about it.

These patterns are helpful knowledge to have. Of course, for those patterns most applicable to the kind of software you deliver, it’ll be beneficial for you to master at least a few of them. You should know these patterns well enough to explain how new team members use them. The number of patterns you’ve mastered is likely to grow, but there will probably always be patterns you don’t use often enough to master genuinely. Which patterns should you go deep in? Well, that depends on what kind of applications you’re building; but I’ll offer some suggestions at the end of this article.

What Makes up a Design Pattern?

What makes up a design pattern? Design patterns are documented descriptions of solutions to common programming problems. The Gang of Four’s book, Design Patterns, helped establish these well-defined sections that are still used today. The first section is the name and classification of the pattern. Second, it’s good to describe the intent of the pattern. What is the problem that it’s trying to solve? What is the goal of the pattern? Many patterns go by numerous names because they exist in the wild, and developers call them by different names. So it’s helpful to represent a given pattern; in other words, it might be known.

We’ll talk about the motivation for the pattern, a scenario or problem that this pattern applies to, and how it can be applied. We’ll talk about the structure of the pattern. This is usually done with class diagrams, interaction diagrams, or sequence diagrams, typically using UML to show how the different parts of this pattern interact. Along with that, there will be some detail about the participants. This is a list of classes and objects used in the pattern; their roles in its design. The next thing we usually cover is a detailed view of collaboration; how do these classes interact?

No alt text provided for this image

You’ll learn how to implement the pattern, representing the solution to the problem earlier in the definition. There should be some sample code in some particular programming language; it varies with the source. After that, you’ll see any known uses of the pattern.

This helps you identify real-world implementations of a pattern that you can look at for future reference and see how it has been applied outside of an academic context. And finally, because many patterns work well, you’ll also see related practices that share some structure but differ in intent or other ways.

Suppose just trying to gain a broad view particular retain idea or concept. In that case, the bare minimum amount you should understand to get to that “awakening stage” of learning is to know its name, its primary name, and any aliases it might go by. This tells you what kind of problem it’s seeking to solve, and this will help you because when you see that kind of problem, you’ll remember that there was a pattern that could be applied there.

Design Pattern Structure

In object-oriented programming, many design patterns are described using diagrams like this. In the diagram below, we have a Client. The Client makes a call to a service, which exposes some methods. There’s also a Proxy, which calls a RealService. The implementation of this interface — this IService — is done either by the Proxy or by the RealService. Now, in this completed UML diagram, we can see that the Client will refer to an abstraction called an “IService” type, and then at runtime, we may have implementations for the Proxy and RealService types that we could swap in as part of this pattern. In diagrams like these, boxes represent classes, or sometimes interfaces in your code lines represent some relationship, such as inheritance or interface implementation, composition, or even invocation-like calls.

No alt text provided for this image

A box may include details about the class’s members, typically with necessary fields or properties listed at the top and methods at the bottom. Not all design patterns are complex. For instance, the singleton pattern’s diagram has just one class. This class has a private _instance field and a static method called Instance that returns a singleton. You’ll have to go deeper to understand a pattern—you should be able to recognize the pattern from its unlabeled diagram.

No alt text provided for this image

However, it is essential to note that different patterns will often share the same structure and differ only in their intent and applicability. You should know the other participants and how they interact. You should already know if you understand the pattern’s structure diagram. Furthermore, you should also be familiar with how to implement the pattern in your programming language of choice. Having done so many times before, you should also understand the consequences and trade-offs of using this particular pattern.

No alt text provided for this image

When Should We Apply Design Patterns?

When should you apply design patterns, especially if you’re still in the overzealous stage of learning? It can be tempting to use a newly learned pattern anywhere and everywhere. But that’s usually not the best approach, especially in production code.

No alt text provided for this image

Starting in a controlled environment is a good idea when deciding how to apply a pattern. Do a coding exercise or kata. Write tests to verify your understanding of how the pattern works. Write tests for the code before you apply the pattern, and then use the pattern and verify that those tests continue to pass and work as they did before. It would be best if you repeated this several times with different variations. Maybe try applying a distinct pattern that you’re already familiar with. Try and compare and contrast the other behavior you get when using one pattern versus your original unmodified code.

Make sure you have test coverage. Whenever you’re doing any refactoring, it’s an excellent idea to make sure you have some tests in place that will verify that your code has not broken with refactoring or applying a design pattern. Do your work in a separate branch and then use a pull request or similar tool to merge it.

Ideally, it would help if you had someone review that code to ensure it looks good before it goes into the main branch. If you have problems or get stuck because you’re unfamiliar with this pattern, be prepared to delete it and start all over. It’s better for you to throw away the code and walk away with the experience and knowledge gained than try to shoehorn a pattern into your production code where it doesn’t fit.

Demo: Practice with Patterns

Let’s look at a demo on how to practice applying design patterns using a coding kata in C#. You should feel free to take this kata and perform it yourself and see how it works for you with the same patterns I’m showing, or even different design patterns that you think could apply in this particular scenario. For this demo, we’re going to use a programming kata. If you’re unfamiliar with katas, you can quickly search online. You’ll find a lot of them.

One of the things that makes this kata different from other exercises you might do is that it comes with the code to start with. You’ll find it here. It includes the requirements for a system that will update items in a store, and the store’s items have a Quality and a SellIn property that will get modified every night as a scheduled job. You can download the code in many different languages from Emily Bache’s resources page at the bottom of this page.

Click on this link: Gilded Rose by Ercin Dedeoglu

No alt text provided for this image

And you’ll find Emily has many resources.

No alt text provided for this image


A Few Good Design Patterns

I promised to recommend a few patterns for you to investigate before this article was over. Here are some excellent starter patterns for C# developers to understand if you’re looking for a starting point.

The strategy design pattern is one of my favorite design patterns.

If you’re working with dependency injection systems, you’re already somewhat familiar with the pattern. It’s worth your time to become more expert with this pattern and recognize when it applies and how to use it with different variations.

No alt text provided for this image

Similarly, another pattern that works well with the strategy pattern is the repository.

The repository pattern is a data access pattern. It can be applied in many ways and has some drawbacks, but overall it tends to decouple your system from its persistence concerns. I like this pattern because you can stack it with other patterns: for instance, I’ve done quite a bit of work with cached repositories, which you’ll find some articles about on my blog. This pattern combines the repository pattern with other things—a decorator and strategy pattern to make it so that you can quickly get colossal performance wins in your applications.

No alt text provided for this image

Another quite common pattern is the adapter.

You probably already know this, even if you don’t recognize its name. You should investigate this article and learn more about how the adapter pattern works and how to apply it. Once you understand that, you’ll see opportunities to use the adapter all over the place in your code, even after you’re out of that overzealous stage of learning. In most systems, we may find that creating objects can be troublesome.

No alt text provided for this image

The factory design pattern is excellent for you to recognize and understand.

This pattern is tightly related to the idea of an IoC container, which I like to say is just a factory on steroids. So if you have a good understanding of the factory design pattern, it will also help you better understand dependency injection and IoC containers. Next, you should probably understand the proxy and decorator patterns. Both these patterns are very closely related, but they have different intents. Structurally they’re almost identical, but their use differs quite significantly. And both are extremely useful for stacking with other patterns.

No alt text provided for this image

And then, lastly, I’d like you to be familiar with the singleton pattern.

This pattern is rarely discussed in Design Patterns because Gang of Four doesn’t think it’s a good pattern for them to discuss. Ultimately, it did get included later on, but many today still consider it an anti-pattern. You should understand how to apply this pattern properly because it’s easy to get wrong, but you should also understand how other ways of solving the problem might be more appropriate.

No alt text provided for this image

?Let’s review the key takeaways from this Introduction to Design Patterns article.

We learned that design patterns are general solutions to existing problems, not just for software code but for building architecture. They apply to a particular context, and initially, they weren’t even a software concept, but the idea was borrowed from city planning and building architecture. Patterns are worth knowing for a variety of reasons: they will help you avoid reinventing the wheel and trying to come up with a solution that may be sub-optimal when a well-known and proven solution already exists; furthermore, using patterns allows you to have higher-level conversations with your team and communicate your intent more clearly in your code.

Although the topic of design patterns is quite expansive, you learned about the value of having a T-shaped knowledge of patterns. You should be familiar with a broad range of patterns, but you should also go deep in your mastery of those most relevant to the kinds of software you write. Practice and follow good refactoring techniques when it comes time to apply patterns, especially while you’re still learning them. Finally, I recommended some excellent patterns to investigate as well.

I suggest that as you learn more patterns, you look for ways to combine them. Often, the most elegant and robust solutions come from applying several different patterns in combination. Thanks for reading this article!

Don’t forget to leave a review, and if you have any questions, leave a comment or find me on Twitter and LinkedIn at "ercindedeoglu".

Until next time, keep improving!

Great work my friend Ercin Dedeoglu ?? I would love to have a detailed discussion on this topic...

要查看或添加评论,请登录

社区洞察

其他会员也浏览了