Design Patterns are solutions to common software design problems that occur over and over in software development.
An adapter helps to join two incompatible interfaces to work together. So, if you have an interface with implementing classes. If you were asked later to add additional sub class(es), but they have incompatible Interface, then, adapter pattern could be useful. There are two structures:
The Adapter has a reference to the incompatible object.
The Adapter has a reference to the incompatible interface.
The decorator pattern extends the functionality of an object dynamically.
Decouples an abstraction from its implementation so that the two can vary independently. As an example, If you have a class called Rectangle. This class could have two different implementations, Red Rectangle and Blue one. Instead of Inheriting from Rectangle class, one for blue rectangle and another for red, We could instead pull out these implementations and use Composition over Inheritance.
It's used to create a tree structure of group of objects. So, an Object can be collection of other objects, where objects share a common interface that defines the common operations.
An object can have a collection of objects called Composite Or Node, while objects that can't have other objects(at the lowest level) called Leaf. Composite object can have leafs or other composites.
Strategy is used when you want to extend the behavior of an Object, where this behavior could vary during the run time. If multiple objects need to use the same behavior(algorithm), we get the benefit of code reuse too.
Dependency is used when you want to separate the dependencies of an Object, and pass them to dependent object during run time. The dependent object does not need to know how to construct the dependencies nor which actual dependencies it is using.
This pattern is used to get a way to access the elements of a collection object in sequential manner without exposing its underlying representation. In this snippet, I am using Java's built-in Iterable & Iterator classes.
Observer pattern is used such that if an object is changed, its dependents objects get notified of that change, Thus, there is 1:M Relationship. As an example, having a Publisher that publish news to the Subscribers, Whenever any new updates or data added, the Subscribers get notified. In this snippet, I am using Java's Observer and Observable classes.
A class behavior may change based on set of states either made by user, or internally by the system. In this pattern, We encapsulate each state. The user doesn't need to know about each state, the user only performs some actions which in turn may change the state of the object.
This pattern defines a way for creating object(s) during run time.
Factory Method is a method used to create object(s) of a certain type(interface) during run time.
Factory Method is an object used to create a set of related objects during run time.
The Singleton Pattern is a pattern that ensures that there is only ever one single instance of a class, And it provides a global way to get to that instance.
This is the basic implementation
If you are concerned about synchronization, eager intantiation could be useful as long as you know you'll always need to instantiate the object, and the object doesn't take a lot of time to load.
Another solution for synchronization using synchronized
method. But, you will pay for it's pitfall; Synchronized code takes a lot longer to run.
The Portotype Pattern used when you want to hide the complexity of creating new instance same as in Factory Pattern, and Creating an object is an expensive operation. Thus, copy an existing object is much efficient. It uses Java's Cloneable Interface for cloning objects.
Using abstract class
Using Interface
I've written these snippets in my free time during my studies. If you find it useful, please support the project by spreading the word.
Contribute by creating new issues, sending pull requests on Github or you can send an email at: omar.elgabry.93@gmail.com
Built under MIT license.