Skip to content

AliakseiFutryn/dotnet-design-patterns-samples

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Samples of .NET design patterns

Here you can find the most popular .NET patterns. You can borrow ideas from this repository and implement them in your solutions. Contributions are always welcome!

Behavioral

  • This pattern can be used, when the object have to change its behavior at runtime. wiki
    • This pattern is recommended in the following cases:
      • You want to create an objech which can change its behavior at runtime.
      • You need to have many strategies of the object behavior.
      • You have to change code behavior at runtime.
  • The visitor pattern describes operation, which should be perform with each object from some hierarchy of classes. The visitor pattern allows to declare a new operation without changing classes of those objects. wiki
    • This pattern is recommended in the following cases:
      • You want to separate an algorithm from an object structure on which it operates.
      • You want to add new operations to extant object structures without modifying the structures.
      • You want to add new operations and do not break open/closed principle.
  • This pattern can be used, when you need to get access to all elements of a composite object without disclosure of its representation. wiki
    • This pattern is recommended in the following cases:
      • You need to implement your own collection with specific logic.
      • You need to implement your own properties and methods which usual collections does not have.
      • You need to iterate elements in a collection by using your own logic.
  • This pattern can be used, when you need to manage memory of managed and unmanaged resources. wiki
    • This pattern is recommended in the following cases:
      • You have to deal with managed and unmanaged resources in your solution.
      • You have to deal with managed resources, make sure that in this case you do not need to use the full version of disposable pattern.
      • You want to control the memory in your application, as it is very important.
  • This pattern can be used, when the behavior of your code should be dependent on some circumstances. wiki
    • This pattern is recommended in the following cases:
      • You have to encapsulate behavior or some algorithm.
      • You have to replace behavior or algorithm at runtime.
      • You have to implement something like sorting, validation, data analys, serialization or etc.
  • This pattern can be used, when you want to have a heap of dependent objects which can notify each other about its changes. wiki
    • This pattern is recommended in the following cases:
      • You have a heap of dependent objects and you want to notify all objects, when one of them was changed.
      • You want to notify some objects, when observer state changed.
      • You have some pieces of your code, which should be notified in case, when observer was changed.
  • This pattern can be used, when you need to interact between two different objects or two different providers. wiki
    • This pattern is recommended in the following cases:
      • You need to interact between one or many different classes.
      • You need to interact between classes which cannot have direct link to each other.
      • You want to change and analyse classes independently.
  • This pattern can be used, when you need to restore an object to its previous state. wiki
    • This pattern is recommended in the following cases:
      • You want to have an opportunity to restore object previous state.
      • You want to restore the previous state of many objects.
      • You want to return to the previous code behavior after sometime.
  • This pattern can be used, when we need to create a system where a sender and receiver will be independend of each other. wiki
    • This pattern is recommended in the following cases:
      • You need to make sender and receiver to be independed of each other.
      • You have to get a command as a result like any other objects.
      • You want to process a command like an object. It will allow you to save command or pass a command as a parameter to methods.
  • This pattern can be used, when you need to interpret some symbol (terminal or non-terminal) into C# computer language. wiki
    • This pattern is recommended in the following cases:
      • You need to evaluate sentences in a language.
      • You need to interpret some symbols into C# langunage.
      • You want to create your own langunage interpreter.
  • This is a design pattern and in the template method of this pattern, one or more algorithm steps can be overridden by subclasses to allow differing behaviors while ensuring that the overarching algorithm is still followed. wiki
    • This pattern is recommended in the following cases:
      • You want create an algorithm with predefined methods where some steps can be overriden by inheritor.
      • You want to create many quite similar classes except some methods.
      • You want to change the behevior at runtime depending on type of classes which should be inherit from one abstract class.
  • This pattern can be used, when we need to oraganize some levels of responsibility in our system/application. wiki
    • This pattern is recommended in the following cases:
      • You have a group of objects, which can handle messages of a certain type.
      • All messages should be handled at least by one handler in a system.
      • The messages in a system handle by the next scheme "Handle by yourself or send to other", it means, that some messages we handle on the level where we get them and the others we send to the objects of another level.

Generating

  • The builder pattern is responsible for separating constructing of large object from his representation. It means, that you can receive different representation after the similar construction process. wiki
    • This pattern is recommended in the following cases:
      • You should construct a large object with many different properties.
      • You should construct one object from another.
  • This is a generating pattern, which provides you with guarantee, that this object is only one in the one-thread application and has global access point. wiki
    • This pattern is recommended in the following cases:
      • You need an instace of an object, which has a single representation withit a system.
      • You need an access to some resource, which is used by different parts of our application like a unity container.
  • This is a generating patter, which is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. wiki
    • This pattern is recommended in the following cases:
      • When you need to avoid subclasses of an object creator in the client application, like the abstract factory pattern does.
      • When you should avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.
  • This is a generating patter, instead of using a null reference to convey absence of an object (for instance, a non-existent customer), one uses an object which implements the expected interface, but whose method body is empty. The advantage of this approach over a working default implementation is that a Null Object is very predictable and has no side effects: it does nothing. wiki
    • This pattern is recommended in the following cases:
      • When you have many objects, which implement special interface and you have to perform some action without any errors.
      • This pattern can also be used to act as a stub for testing, if a certain feature such as a database is not available for testing.
  • The object pool design pattern creates a set of objects that may be reused. When a new object is needed, it is requested from the pool. If a previously prepared object is available it is returned immediately, avoiding the instantiation cost. If no objects are present in the pool, a new item is created and returned. wiki
    • This pattern is recommended in the following cases:
      • You shoul work with a large number of objects that are particularly expensive to instantiate and each object is only needed for a short period of time.
      • You want to improve performance of some piece of code, where you have many objects, which you can reuse.
  • As well you can find a perfect example of object pool pattern from Googler here (answer with number five).
  • This is a generating pattern, it defines an interface for creating objects, however leaves the decision of which class should be created to subclasses. In conclusion, factory method allow class to delegate an instantiation to subclasses. wiki
    • This pattern is recommended in the following cases:
      • The object's creation leads to a significant duplication of code.
      • The object's creation does not provide a sufficient level of abstraction.
      • The object's creation requires information not accessible to the composing object.
  • This is a generating pattern and it represents the strategy for creating a family of dependent or related objects. wiki
    • This pattern is recommended in the following cases:
      • You have to create many different objects and they inherited from the similar class or they have lots of similar properties.
      • You want to change behavior of your code by using different classes which implement a similar interface.

Structural

  • The proxy pattern is a class functioning as an interface to something else. wiki
    • This pattern is recommended in the following cases:
      • You want to add restriction to use some API or resource.
      • You want to do some preparations before accessing the resource.
      • You want to create an interface to a network connection, a large object in memory or something else that is expensive or impossible to duplicate.
  • The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently". wiki
    • This pattern is recommended in the following cases:
      • You need to decouple abstraction from implementation.
      • You have to implement a service where methods should be dependent of internal provider.
      • You have to implement more than one similar classes which should use different data providers.
  • The facade design pattern represent an object that provides a simplified interface to a larger body of code, such as a class library. wiki
    • This pattern is recommended in the following cases:
      • You want to wrap a poorly designed collection of APIs with a single well-designed API.
      • You want to reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system.
      • You want to make a software library easier to use, understand and test, since the facade has convenient methods for common tasks.
  • This is a structural pattern, that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code. wiki
    • This pattern is recommended in the following cases:
      • When you have to create a wrapper, that must respect a particular interface and must support polymorphic behavior.
      • When you have a situation, where classes with different interfaces should work together.
  • The flyweight pattern is used to minimizes memory usage by sharing as much data as possible with other similar objects. wiki
    • This pattern is recommended in the following cases:
      • You want to decrease memory usage in your application.
      • You want to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory.
      • You have some objects in external data structure and you want pass them to the flyweight objects temporarily when they are used.
  • The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. wiki
    • This pattern is recommended in the following cases:
      • You have to add additional behavior to the class without affecting any other objects in this class.
      • You want to create a wrapper which will be responsible for doing some action above the current class.
      • You want to extend the functionality of current class (cache results, manage user access, logging arguments and etc.).
  • This is a structural pattern, that describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly. wiki
    • This pattern is recommended in the following cases:
      • When you have a situation, where you can ignore the difference between compositions of objects and individual objects.
      • When you have a situation, where you are using multiple objects in the same way, and you often have nearly identical code to handle each of them.
  • The specification pattern is a particular software design pattern, whereby business rules can be recombined by chaining the business rules together using boolean logic. wiki
    • This pattern is recommended in the following cases:
      • You want to check that some object is following rules.
      • You want to validate an objects for compliance.
      • You want ot have a flexible solution which will allow you to add new rules for an object in the future.