Decorator mode (11)

Please believe in yourself, please believe in yourself again, please believe in yourself

The previous chapter briefly introduced the bridge mode (10), if you haven't read it, please watch the previous chapter

1. Decorator mode

Refer to the introduction of the decorator pattern in the rookie tutorial: https://www.runoob.com/design-pattern/decorator-pattern.html

The Decorator Pattern allows adding new functionality to an existing object without changing its structure.

This type of design pattern is a structural pattern, which acts as a wrapper around an existing class.

This pattern creates a decorated class that wraps the original class and provides additional functionality while maintaining the integrity of the class method signature.

introduce

Intent: To dynamically add some additional responsibilities to an object. The decorator pattern is more flexible than subclassing in terms of adding functionality.

Main solution: Generally, we often use inheritance to extend a class, because inheritance introduces static features into the class, and with the increase of extended functions, subclasses will expand.

When to use: Extending a class without adding many subclasses.

How to solve: Divide the specific functional responsibilities and inherit the decorator mode at the same time.

Key code: 1. The Component class acts as an abstract role and should not be implemented concretely. 2. The modified class references and inherits the Component class, and the specific extension class overrides the parent class method.

Application examples:
1. Sun Wukong has 72 transformations. When he becomes a "temple", he is still a monkey at all, but he has the function of a temple again.
2. Whether a picture has a frame or not, it can be hung on the wall, but usually it has a frame, and it is actually the frame that is hung on the wall.
Before being hung on a wall, a picture can be glazed and framed; then the picture, glass and frame form one object.

Advantages: The decorating class and the decorated class can develop independently without coupling with each other. The decorating mode is an alternative mode of inheritance. The decorating mode can dynamically extend the function of an implementing class.

Disadvantages: Multi-layer decoration is more complicated.

Usage scenarios: 1. Extend the function of a class. 2. Add functions dynamically and cancel them dynamically.

Note: Inheritance can be replaced.

composition role specific relation effect
Component Drink The base class of the decorated object Dynamically add responsibilities to these objects
ConcreteComponent Coffee and its subclasses EluosiCoffee, SingleCoffee The specific object to be decorated The specific object to be decorated
Decorator Decorator decorator abstract class decorator abstract class
ConcreteDecorator BingDecorator, QiaoKeLiDecorator concrete decorator concrete decorator

image-20230614165054352

2. Decorator mode

It consists of two parts,
one part is the basic type, and the other part is the matching information, which can be used or not, and can be performed multiple times.

Both parts need to inherit a general abstract class.

There are two parts, one is the main body and the other is the strap.

Define a general abstract class

Then the main body implements this abstract class

The attached part implements the abstract class and relies on the subject information

2. A base class Drink

@Data
public abstract class Drink {
    
    
    private BigDecimal price;
    private String desc;

    // 子类进行实现
    public abstract BigDecimal cost();

}

2. Two decorated objects Coffee

public class Coffee extends Drink{
    
    

    @Override
    public BigDecimal cost() {
    
    
        // 计算价格
      return super.getPrice();
    }
}

2.3 Subclass of decoration object Coffee

There are simple Russian coffee, latte coffee, original coffee, poplar coffee

public class EluosiCoffee extends Coffee {
    
    

    public EluosiCoffee() {
    
    
        setDesc("俄罗斯咖啡");
        setPrice(new BigDecimal(15));
    }

}
public class NaTieCoffee extends Coffee {
    
    

    public NaTieCoffee() {
    
    
        setDesc("拿铁咖啡");
        setPrice(new BigDecimal(12));
    }

}

public class SingleCoffee extends Coffee {
    
    

    public SingleCoffee() {
    
    
        setDesc("原咖啡");
        setPrice(new BigDecimal(10));
    }

}
public class YangZhiCoffee extends Coffee {
    
    

    public YangZhiCoffee() {
    
    
        setDesc("杨枝咖啡");
        setPrice(new BigDecimal(15));
    }

}

2.4 Decorator abstract class Decorator

public class Decorator extends Drink{
    
    
    private Drink drink ;
    public Decorator (Drink drink) {
    
    
        this.drink = drink;
    }

    @Override
    public BigDecimal cost() {
    
    
        // 之前的,加上现在的。
       return drink.cost().add(getPrice());
    }

    @Override
    public String getDesc() {
    
    
        return super.getDesc()+""+getPrice() +"&&" +drink.getDesc();
    }
}

2.5 Decorator Subclasses

Can add ice, milk, chocolate, sugar

public class BingDecorator extends Decorator{
    
    

    public BingDecorator(Drink drink) {
    
    
        super(drink);
        setPrice(new BigDecimal(0));
        setDesc("冰");
    }
}
public class MilkDecorator extends Decorator{
    
    

    public MilkDecorator(Drink drink) {
    
    
        super(drink);
        setPrice(new BigDecimal(2));
        setDesc("牛奶");
    }
}
public class QiaoKeLiDecorator extends Decorator{
    
    

    public QiaoKeLiDecorator(Drink drink) {
    
    
        super(drink);
        setPrice(new BigDecimal(3));
        setDesc("巧克力");
    }
}
public class TangDecorator extends Decorator{
    
    

    public TangDecorator(Drink drink) {
    
    
        super(drink);
        setPrice(new BigDecimal(0));
        setDesc("糖");
    }
}

2.6 Client call

@Test
    public void oneTest() {
    
    
        Drink drink = new SingleCoffee();
        log.info("单咖啡:{}",drink.cost());

        drink = new MilkDecorator(drink);

        drink = new TangDecorator(drink);

        log.info("加了牛奶和糖:{}", drink.cost());

        drink = new NaTieCoffee();

        log.info("拿铁:{}", drink.cost());

    }

image-20230614165744103

The decorator and the decorated must be of the same type, that is, they must have a common superclass.

The application of inheritance here is not to realize the duplication of methods, but to realize the matching of types.

Because the decorator and the decorated are of the same type, the decorator can replace the decorated, which gives the decorated a behavior unique to the decorator.

According to the concept of the decorator pattern, we can implement new decorators to add new behaviors at any time. If inheritance is used, the original program must be modified whenever a new behavior needs to be added


The code for this chapter is placed on github:


https://github.com/yuejianli/DesignPattern/tree/develop/Decorator


Thank you for watching, if you like it, please follow me, thank you again!!!

Guess you like

Origin blog.csdn.net/yjltx1234csdn/article/details/131211776