Design Patterns: Learning Path

Jun 4
Engineering

By Ramas Grikštas, Back-End Engineer in the Core Services team at Kilo Health

Design patterns are typical solutions to the most common problems in software design. They help you tackle problems faster and allow you to communicate with other developers more easily. Plenty of us already use this approach, and it’s about time you started, too.

So, how and when should you use design patterns? And even more important – how can you learn them quicker? 

What are design patterns?

Refactoring Guru has concisely summarized what exactly design patterns are: 

Design patterns are typical solutions to common problems in software design. Each pattern is like a blueprint that you can customize to solve a particular design problem in your code.” 

Imagine you need to build different objects by variable value

We can write “if, else” statements and solve them one by one, but this approach that is commonly used in procedural programming wouldn’t be the most effective in Object Oriented Programming (OOP). This is not how someone using OOP would solve the problem at hand.

But before we explore how to use design patterns, let’s check out the benefits they have.

Design patterns have plenty of benefits because they help to:

  • Create reusable, flexible, and easier scalable code.
  • Reduce your code coupling to a minimum.
  • Make communication between designers more efficient – software professionals can immediately picture the high-level design when they refer to the name of the pattern used to solve a particular issue when discussing system design.
  • Provide you with a way to easily solve issues related to software development using a proven solution.
  • Isolate the variability that may exist in the system requirements, making the overall system easier to understand and maintain later.

Design pattern in action

Let’s get back to the issue at hand. You need to build different objects by variable value. What we need to do right now is to try to understand the problem and start to search for the solution using design patterns.

  1. Identify the problem

First, create different objects that implement the same interface by variable value. For instance:

  • $reader = “csv”; -> build: CsvReader class
  • $reader = “json”; -> build: JsonReader class
  1. Find the solution

To find the solution, you will need to use the resources available to you online. The best places I found to read about existing design patterns are:

  • Design patterns listed on the Refactoring page, and
  • DesignPatternsPHP overview, which would be especially useful if you’re searching for patterns with simple examples in PHP language.

For this problem, you don’t need to reinvent the bicycle – Object Oriented Programming has an answer to this problem. I also guarantee that design patterns will have an answer to 90% of the problems you’ve faced before

So, in this case, the correct answer is to use a Factory design pattern. It is a creational design pattern that determines how to create an object’s mechanisms.

So, now you have defined a clear problem, and you have a solution for it. What’s left is to customize and implement it into your code. 

If you don’t understand how this pattern works, don’t worry. Try to read about it a few times, but instead of trying to copy examples, figure out how it really works. Next time you face a similar problem, you will remember this pattern and find a solution faster.

Once you learn these patterns, you can use them in any programming language such as PHP, JAVA, PYTHON, C#, RUBY, GOLANG, etc. 

It might take a slightly different approach to adapt them to different programming languages, but you can always find examples online on how to do that correctly.

Bad example:

<?php

declare(strict_types=1);

// Bad approach - procedural programming way
class Reader
{
    public function read(string $fileExt, string $path): array
    {
        if ($fileExt === "csv") {
            // Csv reading logic
            return [];
        }

        if ($fileExt === "json") {
            // Json reading logic
            return [];
        }

        throw new Exception("Reader not found.");
    }
}

$fileContentFromCsvFile = (new Reader())->read('csv', 'file_path');
$fileContentFromJsonFile = (new Reader())->read('json', 'file_path');

Good example:

<?php

declare(strict_types=1);

// Good approach - factory design pattern
interface ReaderInterface
{
    public function read(string $path): array;
    public function isEligible(string $extension): bool;
}

abstract class Reader implements ReaderInterface
{
    public function isEligible(string $extension): bool
    {
        return $extension === $this->getName();
    }

    abstract public function getName(): string;
}

class CsvReader extends Reader
{
    private const NAME = 'csv';
    public function read(string $path): array {}

    public function getName(): string
    {
        return self::NAME;
    }
}

class JsonReader extends Reader
{
    private const NAME = 'json';
    public function read(string $path): array {}

    public function getName(): string
    {
        return self::NAME;
    }
}

class ReaderFactory
{
    public function __construct(private Collection $readersCollection) {}

    public function build(string $extension): ReaderInterface
    {
        foreach ($this->readersCollection as $reader) {
            if ($reader->isEligible($extension)) {
                return $reader;
            }
        }

        throw new \LogicException('Reader not found!');
    }
}

// Usage: you can bind collection through service providers
$readersCollection = new Collection([
    new CsvReader,
    new JsonReader,
]);
$fileContent = (new ReaderFactory($readersCollection))->build('csv')->read('file_path');

How to learn all design patterns?

There are three main types of design patterns you will encounter in your work as a software engineer. These are:

  • Creational patterns – This type of pattern deals with object creation mechanisms, which increase flexibility and let you reuse your existing code.
  • Structural patterns – This type of pattern eases the design by identifying a simple way to realize relationships between entities.
  • Behavioral patterns – This type of pattern identifies common communication patterns between objects and realizes these patterns. By doing so, these patterns increase more flexibility in carrying out this communication.

Yes, I know that it might seem like a lot, but I’m glad to announce that you don’t need to try to memorize them all at once. They will come to you with your work experience and how much time you spent analyzing them. Also, I can guarantee that not all patterns will be needed for your projects.

When I started to learn these patterns, they looked quite hard. But once you deep-dive into the problem and find a solution, the only thing you need is to just try to figure out how this pattern works and how it solves your problem.

If you manage to implement it to your code once, next time, you will remember how this pattern solves this exact problem.

The second thing is to try and learn only the most common design patterns. Leave the rest for later.

How to learn these patterns faster?

  1. Read programming books about design patterns and about clean code.
  2. Don’t judge yourself if you don’t understand patterns from the first try.
  3. Read different sources of information about patterns and see different solutions and approaches.
  4. Don’t try to learn all the patterns at once. 
  5. Focus on one pattern at a time. 
  6. Try to identify patterns in other people’s code.

Most important of all – try not only to read about the patterns but also to apply them to practice. Create your own project and situation where you would need to use this pattern. It will be like a small practice before really using it.

Cheatsheet of design patterns 

Let’s make life easier for you. I’ve compiled a design patterns list, which I use very often. These patterns are the most common in the PHP programming language, and I think they will help you on your learning journey.

As you already know, there are 3 main types of patterns: creational, structural, and behavioral. Each of them holds several key design patterns you might find useful.

Creational patterns:

  • Factory – helps you build different objects.
  • Builder – helps you build complex objects in a simple way.
  • Singleton – helps you have one class instance in your program.

Structural patterns:

  • Dependency injection – helps you implement a loosely coupled architecture to get better (testable, maintainable, and extendable) code.
  • Adapter – helps you translate one interface into another compatible interface.
  • Bridge – helps you decouple an abstraction from its implementation.
  • Decorator – helps you decorate or extend objects.
  • Facade – helps you decouple a client and a sub-system by embedding many (but sometimes just one) interfaces and, of course, reducing complexity.

Behavioral patterns:

  • Iterator – helps you make an object iterable and make it appear like a collection of objects.
  • Observer – helps you notify other objects about events.
  • Strategy – helps you easily switch between different strategies.
  • Null object – helps you reduce the chance of null pointer exceptions. (NullObject is not a GoF design pattern but a schema that appears frequently enough to be considered a pattern).

More:

  • Repository – helps you mediate between the domain and data mapping layers using a collection-like interface for accessing domain objects.

The risk of overengineering

So, we know that design patterns bring us a lot of benefits. But they also bring more complexity. When you have learned a new design pattern, don’t run to implement this in all places because not every place needs to use them. 

Try to always find at least one reason why this pattern will help you scale your code in the future. If you found at least one reason, go and implement it. 

Sometimes when you don’t see that in the future, you don’t need to touch your code anymore – for instance, to implement a new feature related to this code. In that case, there is no reason to implement a design pattern because it won’t bring you any benefits.

There is no point in implementing a design pattern unless you know that this pattern will give a good performance to your code later on.

Conclusion

Design patterns aren’t hard to learn, but like with everything, it takes time and energy. 

Actually, it’s harder not to learn them but to apply them in everyday life. Don’t push yourself if you don’t understand them from the first time you touch them. 

The understanding will come with time. The only suggestion here is not to apply them to your real projects first – instead, create a test project where you can test your knowledge. 

Read more books, watch videos about clean code, and later, you will have a deeper understanding of how to write more scalable, reusable, and flexible code.

Here are a couple of recommendations I think you’ll find valuable:

  • Head First Design Patterns: A Brain-Friendly Guide
  • Matt Zandstra – PHP 8 Objects, Patterns, and Practice

What books would you recommend for someone who is just starting out?

Ramas Grikstas
Back-End Engineer at Core Marketing Team
Engineer who thrives on building startups.

Latest articles

Leadership Switch at Kilo Health: Zygimantas Surintas as CEO, Tadas Burgaila Leads Development
Apr 19
News

As we’re entering an exciting new chapter of business growth and leadership, it’s the perfect time to catch up on the latest changes in our team and where we’re headed next. Dive in and get to know our new CEO…

Read more
Matas Olendra: Innovators Aren’t Magicians, It’s All About Principles
Mar 15
Kilo Heroes

I’m Matas, and when asked, I refer to myself as an intern — always learning. However, research, strategy, business development, and idea generation are the cornerstones of my work. I want to pull back the curtain and give you an…

Read more
Deimante Butke and her 3 roles: Full-Time Job, Pursuing a PhD, and Motherhood
Feb 15
Kilo Heroes

I’m Deimante, currently Head of Marketing at Kilo Health, and a big lover of this company. My journey to being hired at Kilo has been quite the ride.  How it all started? I underwent interviews with 11 different people and…

Read more
Kilo Health Launches an Incubator Challenge: Ready to Test Yourself in a Startup?
Jan 12
Articles

Ever dreamt of taking the lead, even if the path isn’t crystal clear? Or to have someone believe in you and offer you a chance to figure out whether you would thrive in a startup environment? Speaking of which, Kilo…

Read more
Kilo Health Celebrates Its 10th Anniversary: Milestones and Lessons
Oct 25
News

A whole decade has raced by in the blink of an eye for us at Kilo Health, and what better way to celebrate than to reflect on the milestones and lessons over the years? Do you know where we started?…

Read more
Vitalijus Majorovas: Co-Founders Also Need Balance
Aug 23
Kilo Heroes

We, the co-founders, are just ordinary individuals with grand ambitions. There are times when we work twice as long and intensely as others, yet we’re equipped with the same amount of daytime, energy, and capacity. However, as leaders in the…

Read more
Following Your Gut: How to Avoid the Startup Graveyard
Aug 11
Kilo Heroes

There’s no enchanting tale behind how I became a part of Kilo Health. In truth, some of us regular folks simply have regular journeys, and that’s perfectly fine. What counts is that today, I hold a successful product in my…

Read more
Kilo Health Breaks Records: 84% Growth, 213M Euros in a Year
Aug 8
News

Reflecting on your achievements from the previous year is advantageous. That’s exactly what we did, proudly demonstrating our boundless aspirations through an impressive 84% growth and 213 million euros. So let’s put our hands in the air and celebrate together,…

Read more
I Don’t Need a New Job: Or How to Join Kilo Health Within 10 Minutes
Jul 14
Kilo Heroes

I joined Kilo Health back in 2019, and I can prove that when people’s values and mindsets align, great things can be accomplished, even if you don’t have a plan. BoomeranGO!, the first and only product for children provided by…

Read more
4 Ways Startups Can Draw Inspiration From Hollywood 
Jun 14
Kilo Heroes

Lighting, sound, set, and actors are essential components of a film studio, but they are not the sole factors that define its success.  Consistent creativity, appreciation of talent, and adaptability to market trends are a few of the things that…

Read more
How positive company culture can impact your productivity and growth
Apr 22
News

How valuable is having a good company culture to that company’s bottom line? Very valuable – it’s like liquid gold. A 2019 study conducted by academics from Oxford University and MIT found that workers who experienced a measurable increase in happiness were…

Read more
Internal Career: Why It Benefits Both Employees and Employers?
Apr 5
News

Internal career development opportunities are increasingly recognized as one of the most valuable benefits for employees. In fact, 62% of Learning and Development (L&D) professionals state that they are prioritizing internal mobility in 2024. Moreover, according to data from LinkedIn, individuals who…

Read more

Stay on top of health and wellness news

Kilo Outsider is a curated monthly newsletter for everyone who cares about health – from investors to policy makers, from entrepreneurs to healthy living enthusiasts.