C# Design Patterns - amitbhilagude/userfullinks GitHub Wiki

  1. Strategy Pattern
    1. Most commonly used Strategy Patterns.
    2. Decouple code as much as you and avoid duplicates.
    3. This is implemented by creating an Interface and calling that interface from the method.
    4. This interface may have inherited by multiple classes so we dynamically decide which class to be invoked.
    5. This is how .net core works by adding an interface into the constructor.
    6. This pattern is used for different bookkeeping system which has similar functionality which has common interface and each bookkeeping class has own implementation.
  2. Singleton Pattern
    1. This pattern is used when we wish to instantiate only once throughout the application.
    2. We will have to instantiate this object with lazy loading. Instantiate when it is required.
    3. This will be implemented by the Sealed Class approach and create an instance when it is required.
      1. creating a Sealed Class so that we can't create an object of it.
      2. Having a Private constructor.
      3. Having a Private static variable of the same object
      4. create a public static property that will return an instance of the private static variable of the same object if it does not instantiate yet.
    4. Challenge with this pattern is it is not Thread-safe e.g. If we use TPL parallel library and call this class object then it may instantiate multiple instances due to multiple executions and it may find null for each execution.
    5. Recommended way to implement singleton using Lazy which is available from .Net 4.5.
      1. Create a Sealed Class
      2. Create Private static read-only Lazy _lazy= new ...
      3. Create a static private constructor(This is optional)
      4. Create public static property to return _lazy. Value
  3. Command Pattern
    1. This pattern will create a wrapper on top of business logic. e.g. Don't interact directly with the repository classes but create an ICommand Interface that takes care of this call.
    2. We call invoke method here and provide the command.
    3. It will be decoupled direct call
  4. Bridge Pattern
    1. This pattern will use to abstracts and decouple methods as much as you can.
    2. IF there is a class which has many level hierarchy then we can decouple this hierarchy into two splits and inject second part in constructor reuse it.
    3. E.g. Movie pattern shown in Pluralsight and manage discount for it.
  5. Null Object Pattern
    1. Every property needs to have a null check to avoid a null exception.
    2. Null object pattern recommends creating another class which is inherited the same interface and return that class with a null value check.
    3. E.g. Learner null will have a default value set as shown in Pluralsight.
  6. Specification Design pattern
    1. This pattern is used to avoid duplication and make sure database query is executed in server and no in-memory calculations.
    2. One example here is the use of LINQ query and use where clause in the query itself. This is good practice and SQL query generated which will also have where clause and we don't return lots of information. however, there could scenario that we will have to write where expression at multiple places, and there will be duplication.
    3. Specification pattern is used to avoid such duplication. We can't have a common function and use it there in the Linq query however C# expression will help to solve this problem. c# expression will create a function. Make sure to create generic specifications so that all C# expressions are managed in a single class.
    4. Pluralsight example with Linq with Movie filter based on Rating like children, adults, etc.
  7. State design Pattern
    1. This pattern is used to avoid the complexity increases during state management e.g. Workflow to work with flag and disable or enable conditions.
    2. Pluralsight examples shown that how do we improve by creating context and class for each state and manage the transition state
  8. Repository Pattern
    1. Most commonly used pattern nowadays.
    2. IT decouples API layer or Business Layer with Data Layer
    3. API doesn't need to worry about which ORM is used e.g. is it EF or something else.
    4. You get more control over which object should we return from API.
  9. Unit of Work pattern
    1. This pattern is used on top of the Repository pattern.
    2. If you wish to commit transactions in multiples repositories, One option to use savechanges will be called one for each repository. That will have multiple roundtrips to the database.
    3. Unit of work pattern is another class on top of IRepositories and initialize these IRepository objects and create common EF context and use savechanges only once.
  10. Lazy Loading Pattern
    1. This pattern has many flavors.
      1. Lazy Initialisation This is used for singleton pattern scenarios. Create a private variable and public property. Get it from property if it already have data.
      2. Value header
      3. Virtual Proxy
      4. Ghost Object
      5. Lazy loading pattern is used for Redis cache.
  11. Mediator Pattern
    1. This pattern used when there are a lot of nested objects calls. Objects are getting referenced by other objects and these may refer with initial objects. Object reference structure will look like a graph. Mediator patter will help to solve this complexity. It work work as mediator to communicate to the other objects.
  12. Factory Pattern
    1. Create implementation as much in one Factory and end-user will worry about calling the method and call only a few necessary parameters.
    2. It will reused across entire applications.
    3. Most commonly used in business logic.
    4. Factory Pattern
  13. Observer pattern
    1. It is an observable and subscriber pattern. The observer will take care of updates the subscriber when state gets changed.
    2. E.g. Angular JS, Observer and subscribe for httpclient. Service bus Topics and subscriptions.
    3. Angular JS.
  14. Adapter Pattern
    1. Bridge gap between two different applications.
    2. If you have two applications, with one spitting out output as XML with the other requiring JSON input, then you’ll need an adapter between the two to make them work seamlessly.
  15. CQRS: Command Query Responsibility segregation
    1. Make sure your update mode which is command and read model which queries are separated as Query model will be in lighter size.
  16. Builder Pattern
  17. Anti-Pattern
    1. These are opposite to the pattern where it gives information about how not to solve the problem. Or They are identified as more frequent use patterns which created the problem.
  18. Decorator Pattern
    1. Used for extending existing classes functionality.
    2. IDistributed redis cache get and set key requires multiple classes. This is possible with single IDistributecache implemented.