Intro to Design Patterns in C#
One thing I did not know at first: design patterns are grouped into three categories:
- Creational - Creating objects (e.g. Singleton, Factory)
- Structural - Composing objects and classes (e.g. Adapter, Decorator)
- Behavioural - Managing object interaction and communication (e.g. Observer)
Creational Patterns
Singleton
Ensures a class has only one instance and provides global access to it. Often used for logging, config, or data connections.
You make the constructor private so new instances cannot be created directly. A property manages instance creation and returns
the single instance. For thread safety, use a readonly lock object and wrap access in a lock block.
Factory
Hides the creation logic of objects. You create multiple implementations of an interface, then use a Factory to return the right one
depending on conditions (like a switch). That means consumers do not need to worry about how the object is created.
I saw Carl do this with an Entities Factory that returns impersonated or non-impersonated clients. Very clean and the calling code stays tidy.
Structural Patterns
Adapter
Lets you adapt an existing class to a new interface. Useful when you have legacy code that does not match your new interface. The Adapter class bridges the gap.
Decorator
Adds new behaviour to an object without changing its core logic. You use an abstract decorator class that implements the same interface as the object, pass the original object into it, and then override methods to enhance or change behaviour. Think adding extra text to a log.
Behavioural Patterns
Observer
Automatically reacts to changes in another object. The pattern uses a Subject that holds a list of Observers. Observers can be added or removed, and when the subject's state changes, it notifies all observers to react. This reminded me of delegates, which is probably why it felt familiar.