What design patterns are

2 min read

Design patterns are time-tested, reusable solutions to commonly occurring problems within a given context in software design. They are not specific pieces of code. They are templates, or descriptions of how to solve a problem, that can be used in many different situations. Understanding and applying design patterns helps create more flexible, maintainable and understandable software.

Design patterns provide a shared vocabulary among developers, which makes it easier to talk about software design. They represent best practices that experienced developers have evolved over time.

At a glance

Category Pattern Core intent or problem solved Common C# use case or example
Creational Singleton Ensure a class has only one instance, and provide a global access point. Logging service, configuration manager, database connection pool (conceptually). Lazy<T> for a thread-safe instance.
Creational Factory Method Define an interface for creating an object, but let subclasses decide which class to instantiate. Creating different types of documents in an application, for example WordDocumentFactory and PdfDocumentFactory.
Creational Abstract Factory Provide an interface for creating families of related objects without specifying concrete classes. UI toolkits supporting multiple themes, for example DarkThemeFactory and LightThemeFactory creating buttons and textboxes.
Structural Decorator Attach additional responsibilities to an object dynamically. Adding compression or encryption to streams (CryptoStream wrapping FileStream).
Structural Adapter Convert the interface of a class into another interface clients expect. Making a legacy logging component compatible with a new ILogger interface.
Structural Facade Provide a simplified interface to a complex subsystem. A single OrderPlacementFacade simplifying interactions with the inventory, payment and notification services.
Behavioral Strategy Define a family of algorithms, encapsulate each, and make them interchangeable. Different payment processing strategies, for example CreditCardPaymentStrategy and PayPalPaymentStrategy.
Behavioral Observer Define a one-to-many dependency so that when one object changes state, its dependents are notified. UI event handling (button clicks), stock price updates notifying subscribers. The C# event keyword.
Architectural Repository Mediate between the domain and data mapping layers using a collection-like interface. Abstracting data access logic, for example IProductRepository with methods like GetProductByIdAsync and AddProductAsync.

Each category has its own note: creationalCreational patternsFour patterns for creating objects in a way that suits the situation.Opens in a new tab, structuralStructural patternsFour patterns for composing classes and objects into larger structures.Opens in a new tab and behavioralBehavioral patternsFour patterns for how objects interact and share out responsibilities.Opens in a new tab, plus the Repository patternRepository patternA collection-like interface over data access, and when it is worth adding.Opens in a new tab.

A word of caution

Design patterns are powerful tools, but how well they work depends on understanding the problem they solve and their inherent trade-offs. Blindly applying a pattern can lead to over-engineering. Choose patterns judiciously, focusing on solving the actual problem at hand rather than using a pattern for its own sake.


Sources