Let’s take a look at the decorator pattern following the Java design pattern adapter pattern.
Will be a review ya, will not come to see it together.
Like a sentence: “eight hours for life, eight hours for development”.
If you like it, let’s stick to it!!
‘😁
An old picture, trance to remember the old man
Design Mode series:
- Java Design pattern – singleton pattern
- Java Design Pattern – Factory Pattern (1) Simple Factory pattern
- Java Design Pattern – Factory Pattern (2) Factory method pattern
- Java Design Pattern – Factory Pattern (3) Abstract Factory pattern
- Java Design pattern – Builder pattern
- Java Design pattern – Proxy pattern
- Java Design pattern – Adapter pattern
- Java Design pattern – Decorator pattern
- Java Design pattern – Bridge pattern
- Java Design pattern – Appearance pattern
- Java Design pattern – Composite pattern
- Java Design pattern – Share meta pattern
- Java Design Pattern – Template method pattern
- Java Design pattern – Policy pattern
- Java Design pattern – Chain of Responsibility pattern
- Java Design Pattern – The Mediator pattern
- Java Design Pattern – Observer Pattern (publish/subscribe pattern)
- Continuously updated…
First, the introduction of decorator mode
1) Introduction:
Most office workers have the habit of sleeping in, every morning work time is very tight, so many people in order to sleep for a while, will use a convenient way to solve the breakfast problem. Some people may have pancakes for breakfast. Pancakes can be made with eggs or sausage, but no matter how “extra” they are, they are still pancakes. In real life, it is often necessary to add new functions or beautify the appearance of existing products, such as house decoration, photo and photo frame, etc., which are all decorator modes. In our own industry is this thing has to add demand
In software development, you sometimes want to use existing components. These components may simply perform core functions. But without changing its structure, its functions can be dynamically extended. All of these can be implemented using the decorator pattern.
2) overview
Definition of a Decorator pattern: A pattern that dynamically adds responsibilities (that is, additional functionality) to an object without changing the structure of the existing object.
3) Character structure
- Abstract Component: Defines an abstract interface to specify objects that are ready to receive additional responsibilities.
- ConcreteComponent: Implement abstract artifacts, adding responsibilities to them by decorating roles.
- Decorators: Inherit abstract artifacts and include instances of concrete artifacts that can be subclassed to extend the functionality of the concrete artifacts.
- ConcreteDecorator: A method for implementing abstract decorators and adding additional responsibilities to concrete component objects.
4) Usage scenarios
Extend the functionality of a class.
2, dynamic increase function, dynamic cancel.
It’s basically for scalability.
5) Take an example
Fast food restaurants have fried noodles, fried rice these fast food, can be additional eggs, ham, bacon these side dishes, of course, add side dishes need extra money, the price of each side dish is usually not the same, then the total price will be more troublesome.
This is an example of a fast food restaurant, which at first glance seems ok, but if you want to expand beyond the Fried rice FriedRice and Fried noodies, for example by adding a Fried sweet potato powder, you have to add an extra whole, Further down, repeat the classes for eggs, bacon, and so on. If you increase that much, you get a quasi-explosion, and if you increase that much, it’s very inappropriate.
Too many subclasses are generated. To see what happens next, see 👇 below.
Two, the realization of decorator pattern
2.1, the preface
Next, let’s refactor the code using the decorator pattern to see what changes are made. Take a look at the essence of the decorator pattern.
But the picture is going to change, and it’s going to look like this:
Let’s talk about the difference between this picture and the last one.
- Fried rice noodles
FriedRice and FriedNoodies
Or inheritanceFastFoot
- The previous ingredients
An Egg and Bacon
It’s no longer under fried rice and chow mein, it’s inherited from the abstract ingredient class, and ingredient classGarnish
And inheritance inFastFoot
.
It looks like something’s missing, so let’s take a look at the code.
Let’s define the roles:
- Abstract Components: FastFoot is the fast food class
- Concrete ConcreteComponent: FriedRice and FriedNoodies are FriedRice and fried noodles
- Decorator: Garnish class
- The ConcreteDecorator classes Egg and Bacon are concrete decorators
2.2 code implementation
👇 look at the code step by step to see:
FastFoot interface: namely abstract component
// Fast food interface
public abstract class FastFood {
private float price;
private String desc;
public FastFood(a) {}public FastFood(float price, String desc) {
this.price = price;
this.desc = desc;
}
//set and get methods
public void setPrice(float price) { this.price = price; }
public float getPrice(a) { return price; }
public String getDesc(a) { return desc; }
public void setDesc(String desc) { this.desc = desc; }
public abstract float cost(a); // Get the price
}
Copy the code
FriedRice and FriedNoodies, namely FriedRice and noodles, are concrete components
/ / Fried rice
public class FriedRice extends FastFood {
public FriedRice(a) {
super(10."Fried rice");
}
// Get the price
public float cost(a) {
returngetPrice(); }}/ / Fried noodles
public class FriedNoodles extends FastFood {
public FriedNoodles(a) {
super(12."Fried noodles");
}
// Get the price
public float cost(a) {
returngetPrice(); }}Copy the code
Garnish is the abstract decoration of the ingredients class
public abstract class Garnish extends FastFood {
private FastFood fastFood;
public FastFood getFastFood(a) { return fastFood; }
public void setFastFood(FastFood fastFood) { this.fastFood = fastFood; }
public Garnish(FastFood fastFood, float price, String desc) {
super(price,desc);
this.fastFood = fastFood; }}Copy the code
The Egg and Bacon classes are concrete decorative classes
// Egg ingredients
public class Egg extends Garnish {
public Egg(FastFood fastFood) { super(fastFood,1."Eggs"); }
// Return the money for fried rice and eggs
public float cost(a) { return getPrice() + getFastFood().getPrice(); }
@Override
public String getDesc(a) { return super.getDesc() + getFastFood().getDesc(); }}// Bacon toppings
public class Bacon extends Garnish {
public Bacon(FastFood fastFood) { super(fastFood,2."Bacon"); }
@Override
public float cost(a) { return getPrice() + getFastFood().getPrice(); }
@Override
public String getDesc(a) { return super.getDesc() + getFastFood().getDesc(); }}Copy the code
The test class:
public class Client {
public static void main(String[] args) {
// Order fried rice
FastFood food = new FriedRice();
// The price of the cost
System.out.println(food.getDesc() + "" + food.cost() + "Yuan");
System.out.println("= = = = = = = =");
// Order fried rice with eggs
FastFood food1 = new FriedRice();
food1 = new Egg(food1);
// The price of the cost
System.out.println(food1.getDesc() + "" + food1.cost() + "Yuan");
System.out.println("= = = = = = = =");
// Order chow mein with bacon
FastFood food2 = new FriedNoodles();
food2 = new Bacon(food2);
// The price of the cost
System.out.println(food2.getDesc() + "" + food2.cost() + "Yuan"); }}Copy the code
This solves one of our initial problems. If you need to expand and add a pad Fry, you just need to create a pad fry class that inherits the FastFoot category. If you need to add ingredients, you just need to create a pad Fry class that inherits the Garnish ingredients category. Other codes are not changed, fully in line with the open and closed principle. There are fewer classes than there would have been otherwise. 😁
Third, summary
1. Application scenarios
-
When the system cannot be extended by inheritance or inheritance is not conducive to system expansion and maintenance.
There are two main types of situations in which inheritance is not possible:
- The first is the existence of a large number of independent extensions in the system, to support each combination will generate a large number of subclasses, resulting in an explosive growth in the number of subclasses;
- The second type is because the class definition cannot inherit (such as final classes)
Add responsibilities to a single object dynamically and transparently without affecting other objects.
-
When the functional requirements of an object can be dynamically added or removed.
2. Advantages:
- Decorators are a powerful complement to inheritance and are more flexible than inheritance, dynamically extending functionality to an object without changing the original object, plug and play
- Different effects can be achieved by using different decorative classes and permutations of these decorative classes
- Decorator and decorator classes can be developed independently and not coupled to each other. Decorator pattern is an inherited alternative pattern that can dynamically extend the functionality of an implementation class.
- Decorator mode fully follows the open and closed principle
3. Disadvantages:
- Decorator mode adds many subclasses, and overuse can add complexity to the program. Multi-layer decoration is more complicated.
4. Talk to yourself
You roll me roll, everyone roll, when this road is the end ah. 😇 (or directly to heaven)
Sometimes I want to stop and have a rest. It’s hard to stick to one thing all the time. 😁
Hi, if you happen to read this article and think it’s good for you, give it a thumbs up and let me feel the joy of sharing, Crab. 🤗
If there is something wrong, please don’t add to it!!
Similarly, if there is any doubt, please leave a message or private message, we will reply to you in the first time.
Ongoing update