Mobile access is not good, please visit me Personal blog
Decoration mode
The function of an object is dynamically extended without changing the original class file and using inheritance. It wraps real objects by creating a wrapping object, or decoration.
Characteristics of Decoration Mode
- Decorative objects and real objects have the same interface. In this way, client objects can interact with decorated objects in the same way as real objects.
- Decorative objects contain reference s to a real object
- Decorative objects accept all requests from clients. It forwards these requests to the real object.
- Decorative objects can add additional functionality before or after forwarding these requests. This ensures that additional functions can be added externally without modifying the structure of a given object at runtime. In object-oriented design, the function extension of a given class is usually achieved through inheritance.
Basic Realization of Decoration Mode
The figure above is the structure diagram of the most basic decoration pattern. The following will use swift code to implement a basic decoration pattern:
1). Write a Component interface first
protocol Component {
func operation()
}
2. Write a specific Component object
class ConcreteComponent: Component {
func operation() {
// Implementation of Specific Operation
}
}
3. Write a decorative abstract class
class Decorator: Component {
var component: Component?
func operation() {
component?.operation()
}
}
4. Write specific decorative objects
// Decorative object A
class ConcreteDecoratorA: Decorator {
private var addedState: String?
override func operation() {
super.operation()
addedState = "ConcreteDecoratorA Unique function to distinguish ConcreteDecoratorB"
// Operation of specific decorative object A
}
}
// Decorative object B
class ConcreteDecoratorB: Decorator {
override func operation() {
super.operation()
addedBehavior()
// Operation of Decorative Object B
}
// ConcreteDecorator B's unique method for distinguishing ConcreteDecorator A
private func addedBehavior() {
}
}
Through the above code, we can simply understand the basic implementation process of decoration pattern. Its main purpose is to dynamically expand the function of an object without changing the original class file and using inheritance. Just like the example code above, we can extend the function of the object through ConcreteDecoratorA and ConcreteDecoratorB, so we don't need to change the original class file and use inheritance. To change the source file of ConcreteComponent class can also achieve the effect of expansion.
Solve practical problems with decoration mode (the problem of car purchase and matching)
Let's look at a practical example. For example, when we buy a car, we usually choose a lot of accessories. Next, we use the strategy model to achieve this process. Next, the structure chart is as follows:
Paste the code below:
// Component
protocol Car {
// How much
func howMuch()-> Int
// Display assembly parts
func showParts()
}
// ConcreteComponents
class Suv: Car {
init(owner: String) {
print("\(owner)Bought a car. Suv,10W")
}
func howMuch() -> Int {
return 10
}
func showParts() {}
}
class Mpv: Car {
init(owner: String) {
print("\(owner)Bought a car. Mpv,15W")
}
func howMuch() -> Int {
return 15
}
func showParts() {}
}
// Decorator
class CarParts: Car {
var car: Car?
func howMuch() -> Int {
return car?.howMuch() ?? 0
}
func showParts() {
car?.showParts()
}
func decorator(_ car: Car) -> Car {
self.car = car
return self
}
}
// ConcreteDecorators
class Sofa: CarParts {
override func howMuch() -> Int {
return super.howMuch() + 1
}
override func showParts() {
super.showParts()
print("Selected leather sofa, 1 W")
}
}
class Safety: CarParts {
override func howMuch() -> Int {
return super.howMuch() + 3
}
override func showParts() {
super.showParts()
print("A complete set of safety systems has been selected. W")
}
}
class Engine: CarParts {
override func howMuch() -> Int {
return super.howMuch() + 5
}
override func showParts() {
super.showParts()
print("Matching V8 Engine, 5 W")
}
}
Let's use the above code to see:
//wcl buys a suv
var suv: Car = Suv(owner: "wcl")
//Assembly sofa
suv = Sofa().decorator(suv)
//Assemble engine
suv = Engine().decorator(suv)
//Assembly Safety System
suv = Safety().decorator(suv)
suv.showParts()
print("A total of flowers.\(suv.howMuch())W")
print("\n")
//wcl buys an mpv
var mpv: Car = Mpv(owner: "wcl")
//Assemble engine
mpv = Engine().decorator(mpv)
//Assembly Safety System
mpv = Safety().decorator(mpv)
mpv.showParts()
print("A total of flowers.\(mpv.howMuch())W")
The following is the result of code printing:
wcl bought a Suv, 10W Selected leather sofa, 1W V8 engine, 5W Complete security system, 3W A total of 19 W was spent. wcl bought an Mpv, 15W V8 engine, 5W Complete security system, 3W A total of 23W was spent.
This simplifies the process with decorative mode, and operates on Suv without changing the source files of the two classes of Mpv.
summary
Let's first look at the advantages of decorative patterns:
- Decorative functions in classes can be removed from classes to simplify the original classes
- Effective separation of core responsibilities from decorative functions and removal of duplicate decorative logic in related classes
Disadvantages of decoration mode:
- Although the decoration mode has a higher expansibility and a slightly larger number of classes, how to choose expansibility and conciseness is a problem, and some choices have to be sacrificed.
- It's hard to figure out how many layers a class is decorated, either 1 or 100.
Above is my understanding of the strategy model. If there is something wrong with it, you are welcome to communicate. Finally, thank you for your reading.~~