Design Patterns can be intimidating at first. It’s one of those topics that tends to attract mystery and misunderstanding around itself, making it look like you can only really understand it after you pass through some initiation rite. They have also generated heated debates in software development circles. Some people swear by them, while others argue eloquently to their uselessness and even harmful nature.

This post is aimed at people who are new to the topic and represents an attempt at dispelling some of the dark clouds hovering around it. Where do Design Patterns come from? What are they, really, and what kinds of problems do they solve? What are their benefits and drawbacks? These are the questions we’re hopeful to find some answers to in the following paragraphs.

Origins

The idea of Design Patterns was introduced by Christopher Alexander, an architect, in his 1977 publication, A Pattern Language: Towns, Buildings, Construction.

Alexander noticed there were some design constructs that, when applied to classes of recurring problems, tended to yield the desired results. As such, he decided to document these patterns so that his experience could benefit others and even empower people to ‘design their own’.

In Alexander's own words:

“The elements of this language are entities called patterns. Each pattern describes a problem that occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.” 

A Pattern Language: Towns, Buildings, Construction

One of the most widely-cited examples of such a pattern is ‘a place to wait’. Bus stops and hospital waiting rooms would both qualify as instances of the general design problem that this pattern applies to. The striking high-level differences between these two instances of the problem speak to the generality of the pattern.

Adoption in Software Design

It was Kent Beck, along with Ward Cunningham who started experimenting with the idea of applying patterns to software design, around 1987. Several years later, in 1994, the book Design Patterns: Elements of Reusable Object-Oriented Software (aka Gang of Four, aka GoF) was published, which played a crucial role in the popularization and adoption of the concept in the industry.

In the same book we can find the following, rather detailed, definition of a design pattern in OO:

“A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. The solution is a general arrangement of objects and classes that solve the problem. The solution is customized and implemented to solve the problem in a particular context.” (emphasis mine)

If the above definition still sounds a bit abstract, let’s briefly consider the Decorator Pattern as an example. A Decorator “allows behavior to be added to an individual object, either statically (i.e., at compile time) or dynamically (i.e., at run-time), without affecting the behavior of other objects from the same class”1. It achieves this by subclassing the original object while also holding a reference to it. Then, it can intercept all calls intended for the original object and alter the behavior as desired. This arrangement allows for “multiple Decorators to be stacked on top of each other, each time adding new functionality to the overridden method(s)”1.

Motivation

It's important to stress, even at the price of being repetitive, that design patterns don't solve programming problems in the strict sense, but software design ones. In other words, they are not algorithms, but arrangements of objects and classes that elegantly balance the conflicting forces that give rise to design problems.

So why should we care about software design?

Because, as Heraclitus noted a long time ago: “Everything changes and nothing stands still”.

His saying applies to software at least as much as it does to anything else. Software requirements change often and, if a system isn’t well-designed, keeping it up to date will be a pain.

Design Patterns - bad code vs good code

The above image is a reasonable illustration of the problem. It would be much easier to track a cable in the second half of the image, than it would be in the first. The second setup also makes for a nice top-level view, while the first looks like a perfect mess.

Granted, when there are just a few cables, the effort required to keep them well-organized might not seem worthwhile. As the system grows, however, the benefits far outweigh the effort. In fact, the design effort might well be the decider of the system's long-term survival.

Similarly, it is much harder to understand what a system does, when it is made up of tightly-coupled, all-depending-on-each-other objects with huge methods and no real separation of concerns. The code is harder to navigate and touching any part of it will trigger an avalanche of problems in completely unexpected areas. Investing in things like modularity and separation of concerns will significantly reduce the maintenance burden and provide for code reuse opportunities.

It's not to say that this should, or necessarily could, all be done upfront. Rather, it's about taking the time to perform the necessary refactoring steps as new requirements occur, stressing the current design beyond its intended limits.

Patterns versus Principles

With all this talk of Software Design, one might be wondering why hasn't there been any mention of Design Principles so far. KISS, DRY, Separation of Concerns, Modularity, Least Surprise or even the SOLID principles of OO design – how do these fit in?

Or, to slightly rephrase that: how do Design Patterns relate to Design Principles?

Principles are more general and higher-level than Patterns. They hold true across the whole paradigm. They are not limited to a context. Patterns could be viewed as condensations, or concrete applications, of Principles – recipes for solving context-bound design problems.

The following analogy from a StackOverflow thread illustrates the difference pretty well:

“Principle: We should teach others in order to educate ourselves as well as others, and overall make our nation a progressive nation

Pattern: In our country, each doctor graduate is supposed to teach 6 months in a far-away village to complete his/her degree”

With that said, it follows that a good understanding of basic Design Principles should facilitate a smoother transition to Design Patterns. 

Classification

The classical Design Patterns are usually divided into three groups, as follows:

Creational

These Patterns deal with object creation mechanisms. Their aim is “to separate a system from how its objects are created, composed and represented. They increase the system’s flexibility in terms of the what, who, how and when of object creation”2.

A few common examples:

  • Singleton – ensures that a type has only one instance and controls the global access to it
  • Builder – separates the construction of a complex object from its representation, thus allowing the same construction process to create different representations
  • Factory method – allows a class to defer instantiation to subclasses
Structural

Structural Patterns deal with identifying simple ways of realizing relationships between objects.

Common examples:

  • Adapter – adapts the interface of an existing class to be used from another interface, thus allowing for otherwise incompatible classes to work together
  • Bridge – decouples an abstraction from its implementation so that the two can vary independently
  • Decorator  – allows extending the behavior of certain objects without affecting other objects that belong to the same class
  • Proxy – acts as an interface to another object (e.g. a network connection, a file etc.)
Behavioral

Behavioral Patterns identify and realize common communication patterns between objects.

Common examples:

  • Command – encapsulates an action and its parameters
  • Iterator – provides sequential access to elements of an aggregate object without exposing its underlying representation
  • Mediator – encapsulates how a set of objects interact
  • Strategy – allows for different algorithms belonging to the same family to be selected at runtime

Providing a concrete implementation of a Pattern is beyond the scope of this introductory article. One can, however, refer to the Decorator pattern post for such an example.

All Design Patterns are well-documented in such a way that both the problem and the solution in terms of relationships between classes and objects are easy to understand. To give you an idea, the documentation template described in GoF follows the structure outlined in the table below (extracted from here).

Term

Description

Pattern Name

Describes the essence of the pattern in a short, but expressive, name

Intent

Describes what the pattern does

Also Known As

List any synonyms for the pattern

Motivation

Provides an example of a problem and how the pattern solves that problem

Applicability

Lists the situations where the pattern is applicable

Structure

Set of diagrams of the classes and objects that depict the pattern

Participants

Describes the classes and objects that participate in the design pattern and their responsibilities

Collaborations

Describes how the participants collaborate to carry out their responsibilities

Consequences

Describes the forces that exist with the pattern and the benefits, trade-offs, and the variable that is isolated by the pattern

Pros

There are two major benefits to Design Patterns that are hardly disputable.

The first is they offer time-tested, proven solutions to recurring design problems. These help isolating the areas of the system that are prone to frequent change by promoting modularity and loose coupling. The end result is systems that are easier to understand, maintain and extend.

The second benefit is the common language that patterns provide. It is much easier to refer to a design solution by a standard pattern name, e.g. Decorator, than by ad-hoc descriptions that are more subject to misunderstanding, e.g. 'a wrapper around a base type', 'a type that is both in a <hasa> and an <isa> relationship with the base type' etc.

The following phrase is a perfectly reasonable example of patterns parlance: 'We will use Decorators for our Streams and work around the constructor chaining problem by employing Builders'. Someone with a good understanding of the Decorator and Builder Patterns will know what is meant by that right away.

Cons

On the down side, Patterns tend to introduce additional classes, objects or even entire new layers to the designs they touch. That can equate to extra complexity and in some cases, lower performance.

It can also be relatively easy, especially as a beginner, to misunderstand and misuse these highly abstract constructs. Guidance from a more experienced developer can prove highly valuable in this case. 

Conclusion

Design Patterns can be viewed as condensed pieces of wisdom resulting from craftsmen’s day-to-day struggle with recurring problems. They are a means by which new practitioners encountering the same design problems can tune in to their forerunners’ wisdom and hopefully avoid some of their pains.

Despite their criticism, GoF Design Patterns are being used heavily in various production-ready libraries and frameworks, especially in the realm of statically typed languages (e.g. C++, Java, C#). They make for an interesting and rewarding study. Their value can best be appreciated after having first struggled with the problems they solve.

Further Reading

Below is a list of useful resources for people who are looking to find out more about Patterns:

Share on:

I have read and understood the ASSIST Software website's Terms of Use and Privacy Policy.

Want to stay on top of everything?

Get updates on industry developments and the software solutions we can now create for a smooth digital transformation.

Frequently Asked Questions

1. Can you integrate AI into an existing software product?

Absolutely. Our team can assess your current system and recommend how artificial intelligence features, such as automation, recommendation engines, or predictive analytics, can be integrated effectively. Whether it's enhancing user experience or streamlining operations, we ensure AI is added where it delivers real value without disrupting your core functionality.

2. What types of AI projects has ASSIST Software delivered?

We’ve developed AI solutions across industries, from natural language processing in customer support platforms to computer vision in manufacturing and agriculture. Our expertise spans recommendation systems, intelligent automation, predictive analytics, and custom machine learning models tailored to specific business needs.

3. What is ASSIST Software's development process?  

The Software Development Life Cycle (SDLC) we employ defines the stages for a software project. Our SDLC phases include planning, requirement gathering, product design, development, testing, deployment, and maintenance.

4. What software development methodology does ASSIST Software use?  

ASSIST Software primarily leverages Agile principles for flexibility and adaptability. This means we break down projects into smaller, manageable sprints, allowing continuous feedback and iteration throughout the development cycle. We also incorporate elements from other methodologies to increase efficiency as needed. For example, we use Scrum for project roles and collaboration, and Kanban boards to see workflow and manage tasks. As per the Waterfall approach, we emphasize precise planning and documentation during the initial stages.

5. I'm considering a custom application. Should I focus on a desktop, mobile or web app?  

We can offer software consultancy services to determine the type of software you need based on your specific requirements. Please explore what type of app development would suit your custom build product.   

  • A web application runs on a web browser and is accessible from any device with an internet connection. (e.g., online store, social media platform)   
  • Mobile app developers design applications mainly for smartphones and tablets, such as games and productivity tools. However, they can be extended to other devices, such as smartwatches.    
  • Desktop applications are installed directly on a computer (e.g., photo editing software, word processors).   
  • Enterprise software manages complex business functions within an organization (e.g., Customer Relationship Management (CRM), Enterprise Resource Planning (ERP)).

6. My software product is complex. Are you familiar with the Scaled Agile methodology?

We have been in the software engineering industry for 30 years. During this time, we have worked on bespoke software that needed creative thinking, innovation, and customized solutions. 

Scaled Agile refers to frameworks and practices that help large organizations adopt Agile methodologies. Traditional Agile is designed for small, self-organizing teams. Scaled Agile addresses the challenges of implementing Agile across multiple teams working on complex projects.  

SAFe provides a structured approach for aligning teams, coordinating work, and delivering value at scale. It focuses on collaboration, communication, and continuous delivery for optimal custom software development services. 

7. How do I choose the best collaboration model with ASSIST Software?  

We offer flexible models. Think about your project and see which model would be right for you.   

  • Dedicated Team: Ideal for complex, long-term projects requiring high continuity and collaboration.   
  • Team Augmentation: Perfect for short-term projects or existing teams needing additional expertise.   
  • Project-Based Model: Best for well-defined projects with clear deliverables and a fixed budget.   

Contact us to discuss the advantages and disadvantages of each model. 

1. Is ASSIST Software a reliable company for custom engineering?

Absolutely. Our partners have given us great recommendations and reviews, leading us to win The Manifest Award for Most Reviewed Software Developers. Further proof comes from our 97% employee retention rate and ongoing client partnerships for over 8 years.  

2. Are the ASSIST Software Romanian software engineers certified?

Yes. 85% of our software programmers are certified.  

At a company level, ASSIST Software is certified and recognized by industry players such as Microsoft, AWS, Google Cloud, Adobe, Drupal, Fujitsu, ISTQB, and others.  

Our employee certifications are tremendously important as they reflect the shared commitment to long-term growth.

3. Why should I choose Romania for custom software development? 

Romania has become a significant player in custom software development, attracting businesses worldwide. Romania boasts the highest number of certified IT specialists in Europe and ranks sixth globally, surpassing even the US in tech specialists per capita.  

At ASSIST Software, what sets us apart is our team and our location: our engineers are certified, experienced, and flexible, while being in the +2 GMT time zone allows us to easily facilitate meetings with clients all over the world.

4. What team will work on my project, and where will it be located?

ASSIST Software's headquarters is in Romania, a prime country for software development outsourcing. Our 350+ software engineers speak English and have a deep passion for innovation.  

We provide regular project updates through reports, meetings, and online dashboards. Generally, you'll have access to a dedicated project manager who will be your point of contact for any questions or concerns.  

5. How much will my project cost me?

Our prices are competitive, and as per our working model, we guarantee you will be satisfied with the result. Frequent meetings, check-ins, and a great communication structure will ensure this outcome.   

Project costs depend on various factors, including complexity, scope, required technologies, and team size. We'll gather detailed information about your project during the initial consultation to provide a customized quote and we guarantee that you will be able to see the benefits of bespoke software.  

1. What technologies do you work with?

ASSIST Software tackles your projects with a robust tech stack. We build native and cross-platform mobile apps, craft user-friendly web experiences, and create stunning visuals. 

Our wide-ranging expertise starts from Java, Python, and JavaScript frameworks to cutting-edge solutions like AR/VR, blockchain, and AI/ML. We also manage databases, leverage cloud platforms, and ensure flawless project execution. We're your one-stop shop for exceptional software development from concept to deployment. You can view our expertise for more details.   

2. Are you experienced in AI/ML development?

Yes. We have extensive experience in data engineering and machine learning operations (MLOps). We can employ neural networks, computer vision, and AI models to benefit your ideas.   

You can trust our long-term experience with big data, NLP, and sentiment analysis, as over the past three years, we led a European security project with 15 partners focused on detecting radicalization on social media and the dark web.

3. Do you have a research and development department and work on European Projects?

We know R&D is crucial for businesses to stay competitive and thrive in dynamic markets. Successful R&D efforts lead to developing exceptional products or services, improved efficiency and effectiveness in operations, and enhanced market positioning.   

We have established solid partnerships with 160+ European research companies, universities, and research centers (e.g., Fraunhofer, TWI, University of Heidelberg, REWE Group, SINTEF, etc.) and have participated as technical partners in over 25 EU-funded projects.  

4. Besides custom software solutions, what other services do you offer?

  • Design Thinking for Breakthrough Products:  

    We craft user experiences that resonate. Our design process is an immersive collaboration, starting with workshops to uncover your vision and user needs. We conduct market research, analyze the competition, and guide you toward cutting-edge solutions in accordance with your business requirements.  

  • Digital Transformation to Reimagine Your Business:

    Digital transformation is nothing less than a strategic shift. We empower you to become more agile and data-driven, optimizing core processes for the digital age.  

  • Scale with Confidence as We Build for Growth:  

    We understand that business success and development mean new challenges. Our solutions are built to scale seamlessly, accommodating increasing user bases and data volumes without sacrificing performance or security.  

5. As a company, does ASSIST have its own software products?

Yes, ASSIST Software teams have been involved in designing and developing innovative products that address community needs. One such example is the web and mobile platform Autisma. This therapy assistant enables continued learning for children diagnosed with autism spectrum disorder.   

Our extensive knowledge of the Unity and Unreal engines has allowed us to develop two mobile games, Elly and the Ruby Atlas and Hooman Invaders, as well as various Unity Assets, such as the Real-Time Weather PRO and Easy Sky. These two Unity assets allow Unity developers to control the weather and sky in their projects.   

1. Is ASSIST Software hiring right now?

We are always looking for great people to join our team, whether you're a senior software engineer or a new talent seeking an IT career. Please check our careers page and contact us. Our HR department will contact you as soon as possible.   

2. Is ASSIST Software organizing internships?

Yes. Each year, we organize individual and group internships for students. Our long-term partnership with the Stefan cel Mare University of Suceava allows us to put together great events for students and help them get started in the industry. 

3. What type of learning culture does ASSIST Software encourage?

Our focus on innovation comes from a 'can do' attitude and the continuous learning we encourage our colleagues to pursue. We frequently organize workshops, learning sessions, presentations, and masterclasses. All these events are free and open to our colleagues and aim to support their professional and personal development. 

4. How does ASSIST Software focus on teamwork?

The key to stellar teamwork is the quality time we spend together. ASSIST employees and their families are frequently invited to participate in all activities. We encourage a healthy lifestyle by promoting and organizing hikes, bike riding sessions, marathons, volleyball, football and tennis matches, ping-pong championships, and many more.   

We show our care for the environment through reforestation campaigns and forest cleaning activities.   

We also have an English-speaking club, e-sports gaming nights, tech discussions, networking parties, and board game sessions.   

5. How does ASSIST Software give back to the community?

Volunteering and charity are essential to us, which is why we founded the ASSIST Humanitarian Foundation. We genuinely care about our community and want to improve the future. We invest in IT equipment for schools and award excellent teachers. We also help hospitals and fire departments enter the 21st century.   

We sponsor cultural events and deliver humanitarian aid to those in need. If you agree with our views, you can also donate.   

ASSIST Software Team Members