Good design patterns are crucial in the maintainability of a software system. A system architecture based on good design patterns is more easily understood by the entire team. The team can speak in higher-level abstractions and clearly communicate.
I've added 3 modules to the Pluralsight Design Patterns Library course. These modules are commonly used and are part of the original patterns identified by the Gang of Four.
The observer pattern is very useful in decoupling the source of an event from the object that will do work based on it. If you are looking to understand how the observer pattern allows you to subscribe to external events or without the source knowing about the handling code using IEnumerable or IObservalbe, check out the Observer Pattern in the Design Patterns Library.
Another pattern that is particularly useful is the service locator. Once your application is successfully decoupled the consumers from the services, you'll need a way to discover what services are available to the consumers. The Service Locator is the basic pattern that facilitates that.
A good example of when to use a service locator is when we implement logging. It is used throughout the application and is independent of any particular business function. Initially it is quite easy to implement, but often it needs to be modified as the environment or deployment changes.
Our apps start out with custom logging built by us; usually embedded directly in the application.
As the application evolves, we will break out the logging as a separate function, but in general it is written or tied specifically to the application. To change the logging provider the application must be modified and adapted to the new logging provider.
By adding a service locator between the application and the logging provider, we will be able to abstract the logging provider from the application and the application from the logging provider. This will allow us to change the provider more easily. This can simply be different versions of the same provider or a completely different logging provider.
To understand how to easily implement the service locator, check out the Service Locator module in the DPL.
The state pattern allows the object to change the method's behavior not through configuration but based on the state of the object.
In the state pattern, we create a hidden set of objects that represent the actions of the object for each state. We divide the code into three 3 pieces. The original object, the interface of actions, and a specific implementation for each state.
We see here that the work item will and each of the state objects will implement the same interface. The actions are simplified and reduced to the common actions for each state. In this case, we no longer have a special action to transition between Proposed and Active, we simply will call the SetState action.
The Work Item class will instantiate a state object whenever the state changes and shuttle over any method invocations to the state object.
If you would like to know how to implement the state pattern, check out the State Pattern in the Pluralsight DPL.