Design mode - decorator mode

1. Overview of decorator mode

It refers to dynamically adding some additional responsibilities (i.e. adding some additional functions) to the object without changing the object structure.
Intent: dynamically add some additional responsibilities to an object. Decorator pattern is more flexible than subclassing in terms of adding functionality.

Usage scenarios: 1. Extend the functions of a class. 2. Dynamically add functions and undo them.

Main solution: in general, we often use inheritance to extend a class. Because inheritance introduces static features into the class, and with the increase of extension functions, subclasses will expand.
Decorator mode has the following roles:

  • Abstract component: defines an object whose interface receives additional responsibilities
  • Concrete construction: Abstract construction is realized, and responsibilities are added through decorating roles
  • Abstract decoration: inherit or implement Abstract construction, and hold an instance of a specific component, which can extend specific functions through its subclasses.
  • Concrete decoration: the method of implementing abstract decoration and adding additional responsibilities to concrete construction objects.

Now we introduce such a scenario. Fast food restaurants often have a variety of choices such as fried noodles, fried rice and fried noodles. They often need to add eggs and sausages to these things. Combined with the due role of decorator mode, we draw the following UML class diagram:

  • FastFood: corresponding abstract component class.
  • FriedRice and FriedNoodles: corresponding to specific component classes
  • Fooddecorator: corresponding abstract decoration
  • Egg and Backon correspond to specific decoration classes.
public abstract class FastFood {
    protected float price;
    protected String desc;

    public FastFood(float price,String desc){
        this.price=price;
        this.desc=desc;
    }

    public FastFood(){

    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
    public abstract float getCost();
}
public class FriedNoodles extends FastFood{


    public FriedNoodles(float price,String desc){
        super(12,"Stir-Fried Noodles with Vegetables");
    }
    @Override
    public float getCost() {
        return getPrice();
    }
}


public class FriedRice extends FastFood{


    public FriedRice(){
        super(10,"Fried rice");
    }


    @Override
    public float getCost() {
        return getPrice();
    }
}



public abstract class FoodDeractor extends FastFood{

    protected FastFood fastFood;

    public FoodDeractor(float price,String desc,FastFood fastFood){
        super(price,desc);
        this.fastFood=fastFood;
    }

}


public class Egg extends FoodDeractor{


    public Egg(FastFood fastFood){
        super(1,"egg",fastFood);
    }
    @Override
    public float getCost() {
        return getPrice()+fastFood.getPrice();
    }

    @Override
    public String getDesc(){
        return super.getDesc()+fastFood.getDesc();
    }
}


public class Client {
    public static void main(String[] args) {
        FastFood rice=new FriedRice();
        System.out.println(rice.getDesc()+rice.getCost());

        rice=new Egg(rice);

        System.out.println(rice.getDesc());
        System.out.println(rice.getCost());
        //Fried rice 10.0
		//Stir-Fried Rice with Egg
		//11.0

In fact, the purpose of abstract modification class inheritance and abstract construction is not to inherit its behavior, but to need its type. The object holding the abstract component class is to add or add its functions on the basis of its methods.

Imagine if we don't do this, we must create a FriedRiceEgg class, and it can't be guaranteed that it will be used. When adding new dishes, the side dishes and main dishes need two-way expansion, which will cause class explosion.

Tags: Java Design Pattern

Posted on Wed, 13 Oct 2021 15:24:16 -0400 by it2051229