Notes on "Java Design Patterns"-Chapter 11 Decorator Pattern

statement:

This blog is my notes after studying "Java Design Patterns". It is intended to facilitate review and review, and is not for commercial use.

This blog has indicated the source, if there is any infringement, please inform and delete it immediately.

1. Explanation of Decorator Mode

  • Definition: On the basis of not changing the original object, attach the function to the object .
  • Provides a more flexible alternative than inheritance (expanding the original object function)
  • Type: Structural
  • Extend the functionality of a class or add additional responsibilities to a class
  • Dynamically add functions to an object, these functions can be dynamically undone
  • advantage
    • A powerful supplement to inheritance, which is more flexible than inheritance. It can extend functions to an object without changing the original object.
    • Different effects can be achieved by using different decorations and the permutation and combination of these decorations
    • Comply with the opening and closing principle
  • Disadvantage
    • There will be more codes, more classes, and increased program complexity
    • Dynamic decoration is more complicated when multi-layer decoration
  • Related design patterns
    • Decorator mode and proxy mode
      • Decorator mode focuses on dynamically adding methods to an object
      • The proxy mode focuses on controlling access to objects, and the proxy class can hide specific information about an object from its clients
      • Usually when we use the proxy mode, we often create an instance of a class in a proxy class, and when we use the decorator mode, we usually pass the original object as a parameter to the constructor of the decorator
    • Decorator pattern and adapter pattern
      • Both decorator mode and adapter mode can be called packaging mode
      • The decorator and the decorate can implement the same interface, or the decorator is a subclass of the decorate
      • The adapter and the adapted class have different interfaces

2. Decorator mode Coding

Now we simulate a business scenario of selling pancakes:

  1. Create pancake class

    public class Battercake {
          
          
        protected String getDesc() {
          
          
            return "煎饼";
        }
        protected int cost() {
          
          
            return 8;
        }
    }
    
  2. Create pancakes with eggs

    public class BattercakeWithEgg extends Battercake {
          
          
        @Override
        public String getDesc() {
          
          
            return super.getDesc()+"加一个鸡蛋";
        }
    
        @Override
        public int cost() {
          
          
            return super.cost()+1;
        }
    
    }
    
  3. Create pancakes with eggs and sausages

    public class BattercakeWithEggSausage extends BattercakeWithEgg{
          
          
        @Override
        public String getDesc() {
          
          
            return super.getDesc()+"加一个香肠";
        }
    
        @Override
        public int cost() {
          
          
            return super.cost()+2;
        }
    }
    
  4. Test class

    public class Test {
          
          
        public static void main(String[]args){
          
          
            Battercake battercake = new Battercake();
            System.out.println(battercake.getDesc()+"销售价格:"+battercake.cost());
    
            BattercakeWithEgg battercakeWithEgg = new BattercakeWithEgg();
            System.out.println(battercakeWithEgg.getDesc()+"销售价格:"+battercakeWithEgg.cost());
    
            BattercakeWithEggSausage battercakeWithEggSausage = new BattercakeWithEggSausage();
            System.out.println(battercakeWithEggSausage.getDesc()+"销售价格:"+battercakeWithEggSausage.cost());
    
        }
    }
    

    operation result:

    煎饼销售价格:8
    煎饼加一个鸡蛋销售价格:9
    煎饼加一个鸡蛋加一个香肠销售价格:11
    

If someone wants to add two eggs, then we have to create a pancake and two egg classes, which is very poorly expandable through inheritance.

Below we use the decorator pattern:

  1. Create abstract pancake class

    public abstract class ABattercake {
          
          
        protected abstract String getDesc();
        protected abstract int cost();
    }
    
  2. Create a pancake class and inherit from the abstract jianbing class

    public class Battercate extends ABattercake {
          
          
        @Override
        protected String getDesc() {
          
          
            return "煎饼";
        }
    
        @Override
        protected int cost() {
          
          
            return 8;
        }
    }
    
  3. Create abstract decorator classes to inherit abstract entities

    public class AbstractDecorator extends ABattercake{
          
          
        private ABattercake aBattercake;
    
        public AbstractDecorator(ABattercake aBattercake) {
          
          
            this.aBattercake = aBattercake;
        }
    
        @Override
        protected String getDesc() {
          
          
            return aBattercake.getDesc();
        }
    
        @Override
        protected int cost() {
          
          
            return aBattercake.cost();
        }
    }
    
  4. The decoration class of pancakes with eggs inherited from the abstract decoration class

    public class EggDecorator extends AbstractDecorator {
          
          
    
        public EggDecorator(ABattercake aBattercake) {
          
          
            super(aBattercake);
        }
    
        @Override
        protected String getDesc() {
          
          
            return super.getDesc() + "加一个鸡蛋";
        }
    
        @Override
        protected int cost() {
          
          
            return super.cost() + 1;
        }
    }
    
  5. The decoration class of pancakes with sausage is inherited from the abstract decoration class

    public class SausageDecorator extends AbstractDecorator {
          
          
    
        public SausageDecorator(ABattercake aBattercake) {
          
          
            super(aBattercake);
        }
    
        @Override
        protected String getDesc() {
          
          
            return super.getDesc() + "加一根香肠";
        }
    
        @Override
        protected int cost() {
          
          
            return super.cost() + 2;
        }
    }
    
  6. For the test category, a pancake with two eggs and one sausage

    public class Test {
          
          
        public static void main(String[] args) {
          
          
            ABattercake aBattercake = new Battercate();
            aBattercake = new EggDecorator(aBattercake);
            aBattercake = new EggDecorator(aBattercake);
            aBattercake = new SausageDecorator(aBattercake);
            System.out.println(aBattercake.getDesc() + " 价格:"+aBattercake.cost());
        }
    }
    

    operation result:

    煎饼加一个鸡蛋加一个鸡蛋加一根香肠 价格:12
    

The class diagram now looks like this:
Insert picture description here

Guess you like

Origin blog.csdn.net/bm1998/article/details/113094757