设计模式
一、设计模式的分类
设计模式主要分为三种类型:
1.1 Creational
These design patterns are all about class instantiation or object creation. These patterns can be further categorized into Class-creational patterns and object-creational patterns. While class-creation patterns use inheritance effectively in the instantiation process, object-creation patterns use delegation effectively to get the job done.
Creational design patterns are the Factory Method, Abstract Factory, Builder, Singleton, Object Pool, and Prototype.
1.2 Structural
These design patterns are about organizing different classes and objects to form larger structures and provide new functionality.
Structural design patterns are Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Private Class Data, and Proxy.
1.3 Behavioral
Behavioral patterns are about identifying common communication patterns between objects and realize these patterns.
Behavioral patterns are Chain of responsibility, Command, Interpreter, Iterator, Mediator, Memento, Null Object, Observer, State, Strategy, Template method, Visitor
二、Creational型设计模式
2.1 Singleton
场景:IP生成器
Singleton pattern is a design pattern which restricts a class to instantiate its multiple objects. It is nothing but a way of defining a class. Class is defined in such a way that only one instance of the class is created in the complete execution of a program or project. Singleton classes are used for logging, driver objects, caching and thread pool, database connections.
An implementation of singleton class should have following properties:
- It should have only one instance : This is done by providing an instance of the class from within the class. Outer classes or subclasses should be prevented to create the instance. This is done by making the constructor private in java so that no class can access the constructor and hence cannot instantiate it.
- Instance should be globally accessible : Instance of singleton class should be globally accessible so that each class can use it. In Java, it is done by making the access-specifier of instance public
Initialization Types of Singleton
Singleton class can be instantiated by two methods:
-
Early initialization : In this method, class is initialized whether it is to be used or not. The main advantage of this method is its simplicity. You initiate the class at the time of class loading. Its drawback is that class is always initialized whether it is being used or not.
- Lazy initialization : In this method, class in initialized only when it is required. It can save you from instantiating the class when you don’t need it. Generally, lazy initialization is used when we create a singleton class.
2.2 Factory Method(TODO)
In Factory pattern, we create object without exposing the creation logic to client and the client use the same common interface to create new type of object.
The idea is to use a static member-function (static factory method) which creates & returns instances, hiding the details of class modules from user.
A factory pattern is one of the core design principles to create an object, allowing clients to create objects of a library(explained below) in a way such that it doesn’t have tight coupling with the class hierarchy of the library.
2.3 Abstract Factory
场景:创建新机头
https://www.geeksforgeeks.org/abstract-factory-pattern/
Abstract Factory pattern is almost similar to Factory Pattern is considered as another layer of abstraction over factory pattern. Abstract Factory patterns work around a super-factory which creates other factories.
Abstract factory pattern implementation provides us a framework that allows us to create objects that follow a general pattern. So at runtime, abstract factory is coupled with any desired concrete factory which can create objects of desired type.
UML class diagram example for the Abstract Factory Design Pattern.
- AbstractFactory : Declares an interface for operations that create abstract product objects.
- ConcreteFactory : Implements the operations declared in the AbstractFactory to create concrete product objects.
- Product : Defines a product object to be created by the corresponding concrete factory and implements the AbstractProduct interface.
- Client : Uses only interfaces declared by AbstractFactory and AbstractProduct classes.
Abstract Factory provides interfaces for creating families of related or dependent objects without specifying their concrete classes.
Client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the concrete objects that are part of the family of objects.
The client does not know or care which concrete objects it gets from each of these concrete factories since it uses only the generic interfaces of their products.
So with this idea of Abstract Factory pattern, we will now try to create a design that will facilitate the creation of related objects.
2.4 Prototype
场景:创建新机头
https://www.geeksforgeeks.org/prototype-design-pattern/
Prototype allows us to hide the complexity of making new instances from the client. The concept is to copy an existing object rather than creating a new instance from scratch, something that may include costly operations. The existing object acts as a prototype and contains the state of the object. The newly copied object may change same properties only if required. This approach saves costly resources and time, especially when the object creation is a heavy process.
The prototype pattern is a creational design pattern. Prototype patterns is required, when object creation is time consuming, and costly operation, so we create object with existing object itself. One of the best available way to create object from existing objects are clone() method. Clone is the simplest approach to implement prototype pattern. However, it is your call to decide how to copy existing object based on your business model.
Prototype Design Participants
1) Prototype : This is the prototype of actual object.
2) Prototype registry : This is used as registry service to have all prototypes accessible using simple string parameters.
3) Client : Client will be responsible for using registry service to access prototype instances.
三、Structual型设计模式
3.1 Adapter
3.2 Bridge
https://www.geeksforgeeks.org/bridge-design-pattern/
3.3 Composite
https://www.geeksforgeeks.org/composite-design-pattern/
3.4 Decorator
场景:EFS portal计价
https://www.geeksforgeeks.org/the-decorator-pattern-set-2-introduction-and-design/
What we get in the end is a pizza with cheeseburst and capsicum toppings. Visualize the “decorator” objects like wrappers. Here are some of the properties of decorators:
- Decorators have the same super type as the object they decorate.
- You can use multiple decorators to wrap an object.
- Since decorators have same type as object, we can pass around decorated object instead of original.
- We can decorate objects at runtime.
Definition:
The decorator pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
Class Diagram:
mage src: Wikipedia
- Each component can be used on its own or may be wrapped by a decorator.
- Each decorator has an instance variable that holds the reference to component it decorates(HAS-A relationship).
- The ConcreteComponent is the object we are going to dynamically decorate.
Advantages:
- The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime.
- The decorator pattern is an alternative to subclassing. Subclassing adds behavior at compile time, and the change affects all instances of the original class; decorating can provide new behavior at runtime for individual objects.
- Decorator offers a pay-as-you-go approach to adding responsibilities. Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects.
Disadvantages:
- Decorators can complicate the process of instantiating the component because you not only have to instantiate the component, but wrap it in a number of decorators.
- It can be complicated to have decorators keep track of other decorators, because to look back into multiple layers of the decorator chain starts to push the decorator pattern beyond its true intent.
3.5 Facade
场景:cssp为newBSS和神机提供接口
https://www.geeksforgeeks.org/facade-design-pattern-introduction/
As the name suggests, it means the face of the building. The people walking past the road can only see this glass face of the building. They do not know anything about it, the wiring, the pipes and other complexities. It hides all the complexities of the building and displays a friendly face.
In Java, the interface JDBC can be called a facade because, we as users or clients create connection using the “java.sql.Connection” interface, the implementation of which we are not concerned about. The implementation is left to the vendor of driver.
Another good example can be the startup of a computer. When a computer starts up, it involves the work of cpu, memory, hard drive, etc. To make it easy to use for users, we can add a facade which wrap the complexity of the task, and provide one simple interface instead. It hides the complexities of the system and provides an interface to the client from where the client can access the system.
When Should this pattern be used?
The facade pattern is appropriate when you have a complex system that you want to expose to clients in a simplified way, or you want to make an external communication layer over an existing system which is incompatible with the system. Facade deals with interfaces, not implementation. Its purpose is to hide internal complexity behind a single interface that appears simple on the outside.
3.6 Flyweight
场景:机头维护
https://www.geeksforgeeks.org/flyweight-design-pattern/
Flyweight pattern is used when we need to create a large number of similar objects (say 105). One important feature of flyweight objects is that they are immutable. This means that they cannot be modified once they have been constructed.
In Flyweight pattern we use a HashMap that stores reference to the object which have already been created, every object is associated with a key. Now when a client wants to create an object, he simply has to pass a key associated with it and if the object has already been created we simply get the reference to that object else it creates a new object and then returns it reference to the client.
3.7 Private Class Data
3.8 Proxy
场景:API鉴权校验
https://www.geeksforgeeks.org/proxy-design-pattern/
Proxies are also called surrogates, handles, and wrappers. They are closely related in structure, but not purpose, to Adapters and Decorators.
Proxy pattern “Controls and manage access to the object they are protecting“.
As in the decorator pattern, proxies can be chained together. The client, and each proxy, believes it is delegating messages to the real server:
Types of proxies
Remote proxy:
They are responsible for representing the object located remotely. Talking to the real object might involve marshalling and unmarshalling of data and talking to the remote object. All that logic is encapsulated in these proxies and the client application need not worry about them.
Virtual proxy:
These proxies will provide some default and instant results if the real object is supposed to take some time to produce results. These proxies initiate the operation on real objects and provide a default result to the application. Once the real object is done, these proxies push the actual data to the client where it has provided dummy data earlier.
Protection proxy:
If an application does not have access to some resource then such proxies will talk to the objects in applications that have access to that resource and then get the result back.
Smart Proxy:
A smart proxy provides additional layer of security by interposing specific actions when the object is accessed. An example can be to check if the real object is locked before it is accessed to ensure that no other object can change it.
Benefits:
- One of the advantages of Proxy pattern is security.
- This pattern avoids duplication of objects which might be huge size and memory intensive. This in turn increases the performance of the application.
- The remote proxy also ensures about security by installing the local code proxy (stub) in the client machine and then accessing the server with help of the remote code.
Drawbacks/Consequences:
This pattern introduces another layer of abstraction which sometimes may be an issue if the RealSubject code is accessed by some of the clients directly and some of them might access the Proxy classes. This might cause disparate behaviour.
Interesting points:
- There are few differences between the related patterns. Like Adapter pattern gives a different interface to its subject, while Proxy patterns provides the same interface from the original object but the decorator provides an enhanced interface. Decorator pattern adds additional behaviour at runtime.
四、Behavioral型设计模式
4.1 Chain of responsibility(TODO)
4.2 Command(TODO)
4.3 Interpreter(TODO)
4.4 Iterator(TODO)
4.5 Mediator(TODO)
4.6 Memento(TODO)
4.7 Null Object(TODO)
4.8 Observer
场景:机头接收配置更新
https://www.geeksforgeeks.org/observer-pattern-set-1-introduction/
https://www.geeksforgeeks.org/observer-pattern-set-2-implementation/
Definition:
The Observer Pattern defines a one to many dependency between objects so that one object changes state, all of its dependents are notified and updated automatically.
Explanation:
- One to many dependency is between Subject(One) and Observer(Many).
- There is dependency as Observers themselves don’t have access to data. They are dependent on Subject to provide them data.
Suppose we are building a cricket app that notifies viewers about the information such as current score, run rate etc. Suppose we have made two display elements CurrentScoreDisplay and AverageScoreDisplay. CricketData has all the data (runs, bowls etc.) and whenever data changes the display elements are notified with new data and they display the latest data accordingly
4.9 State(TODO)
4.11 Strategy
场景: 挑选空闲机头的策略
Definition:
Wikipedia defines strategy pattern as:
“In computer programming, the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm’s behavior to be selected at runtime. The strategy pattern
- defines a family of algorithms,
- encapsulates each algorithm, and
- makes the algorithms interchangeable within that family.”
Here we rely on composition instead of inheritance for reuse. Context is composed of a Strategy. Instead of implementing a behavior the Context delegates it to Strategy. The context would be the class that would require changing behaviors. We can change behavior dynamically. Strategy is implemented as interface so that we can change behavior without affecting our context.
We will have a clearer understanding of strategy pattern when we will use it to solve our problem.
Advantages:
- A family of algorithms can be defined as a class hierarchy and can be used interchangeably to alter application behavior without changing its architecture.
- By encapsulating the algorithm separately, new algorithms complying with the same interface can be easily introduced.
- The application can switch strategies at run-time.
- Strategy enables the clients to choose the required algorithm, without using a “switch” statement or a series of “if-else” statements.
- Data structures used for implementing the algorithm are completely encapsulated in Strategy classes. Therefore, the implementation of an algorithm can be changed without affecting the Context class.
Disadvantages:
- The application must be aware of all the strategies to select the right one for the right situation.
- Context and the Strategy classes normally communicate through the interface specified by the abstract Strategy base class. Strategy base class must expose interface for all the required behaviours, which some concrete Strategy classes might not implement.
- In most cases, the application configures the Context with the required Strategy object. Therefore, the application needs to create and maintain two objects in place of one.
4.12 Template method(TODO)
4.13 Visitor(TODO)
Refernces:
https://www.geeksforgeeks.org/design-patterns-set-1-introduction/
https://www.geeksforgeeks.org/design-patterns-set-2-factory-method/