The Decorator Model of JAVA Design Model

Keywords: Java

It took a long time to understand this model, but it was a little hard to understand at first.

Definition: Adding additional responsibilities to an object dynamically, like painting a wall. Using Decorator mode is more flexible than extending functions by generating subclasses.
Design intention: Inheritance is usually used to expand functions. If there are many kinds of functions that need to be expanded, many subclasses will be generated, which will increase the complexity of the system. At the same time, using inheritance to expand functions, we must foresee these extended functions. These functions are determined at compile time and are static.

 

Points: Decorators and the decorated have a common superclass. The purpose of inheritance is to inherit the type, not the behavior.


In fact Java The I/O API is implemented using Decorator.

 

  1. //Define the Decorated  
  2. public interface Human {  
  3.     public void wearClothes();  
  4.   
  5.     public void walkToWhere();  
  6. }  
  7.   
  8. //Define Decorator  
  9. public abstract class Decorator implements Human {  
  10.     private Human human;  
  11.   
  12.     public Decorator(Human human) {  
  13.         this.human = human;  
  14.     }  
  15.   
  16.     public void wearClothes() {  
  17.         human.wearClothes();  
  18.     }  
  19.   
  20.     public void walkToWhere() {  
  21.         human.walkToWhere();  
  22.     }  
  23. }  
  24.   
  25. //The following three kinds of decoration are defined. This is the first one. The second and third functions are refined in turn. That is to say, the function of the decorator is more and more.  
  26. public class Decorator_zero extends Decorator {  
  27.   
  28.     public Decorator_zero(Human human) {  
  29.         super(human);  
  30.     }  
  31.   
  32.     public void goHome() {  
  33.         System.out.println("Get into the house.");  
  34.     }  
  35.   
  36.     public void findMap() {  
  37.         System.out.println("Looking for the study Map. . ");  
  38.     }  
  39.   
  40.     @Override  
  41.     public void wearClothes() {  
  42.         // TODO Auto-generated method stub  
  43.         super.wearClothes();  
  44.         goHome();  
  45.     }  
  46.   
  47.     @Override  
  48.     public void walkToWhere() {  
  49.         // TODO Auto-generated method stub  
  50.         super.walkToWhere();  
  51.         findMap();  
  52.     }  
  53. }  
  54.   
  55. public class Decorator_first extends Decorator {  
  56.   
  57.     public Decorator_first(Human human) {  
  58.         super(human);  
  59.     }  
  60.   
  61.     public void goClothespress() {  
  62.         System.out.println("Look in the wardrobe.");  
  63.     }  
  64.   
  65.     public void findPlaceOnMap() {  
  66.         System.out.println("stay Map Look up.");  
  67.     }  
  68.   
  69.     @Override  
  70.     public void wearClothes() {  
  71.         // TODO Auto-generated method stub  
  72.         super.wearClothes();  
  73.         goClothespress();  
  74.     }  
  75.   
  76.     @Override  
  77.     public void walkToWhere() {  
  78.         // TODO Auto-generated method stub  
  79.         super.walkToWhere();  
  80.         findPlaceOnMap();  
  81.     }  
  82. }  
  83.   
  84. public class Decorator_two extends Decorator {  
  85.   
  86.     public Decorator_two(Human human) {  
  87.         super(human);  
  88.     }  
  89.   
  90.     public void findClothes() {  
  91.         System.out.println("Find one D&G. . ");  
  92.     }  
  93.   
  94.     public void findTheTarget() {  
  95.         System.out.println("stay Map Find mysterious gardens and castles.");  
  96.     }  
  97.   
  98.     @Override  
  99.     public void wearClothes() {  
  100.         // TODO Auto-generated method stub  
  101.         super.wearClothes();  
  102.         findClothes();  
  103.     }  
  104.   
  105.     @Override  
  106.     public void walkToWhere() {  
  107.         // TODO Auto-generated method stub  
  108.         super.walkToWhere();  
  109.         findTheTarget();  
  110.     }  
  111. }  
  112.   
  113. //Define the adornee. The adornee has some adornment of his own in the initial state.  
  114. public class Person implements Human {  
  115.   
  116.     @Override  
  117.     public void wearClothes() {  
  118.         // TODO Auto-generated method stub  
  119.         System.out.println("What do you wear?");  
  120.     }  
  121.   
  122.     @Override  
  123.     public void walkToWhere() {  
  124.         // TODO Auto-generated method stub  
  125.         System.out.println("Where to go?");  
  126.     }  
  127. }  
  128. //Test classes, take a look and you'll see how similar I/O operations are to java  
  129. public class Test {  
  130.     public static void main(String[] args) {  
  131.         Human person = new Person();  
  132.         Decorator decorator = new Decorator_two(new Decorator_first(  
  133.                 new Decorator_zero(person)));  
  134.         decorator.wearClothes();  
  135.         decorator.walkToWhere();  
  136.     }  
  137. }  

Operation results:

In fact, it is a process of going into the house to find clothes and then finding maps, which enriches the details through the decorator's three-tier decoration.

Key points:
1. Decorator abstract class holds the Human interface, and all methods are delegated to the interface call. The purpose is to give the implementation class of the interface, i.e. subclass, to make the call.
2. Decorator abstract class subclass (concrete decorator), there is a constructor called super(human), this sentence reflects the principle that abstract class depends on subclass implementation, that is, Abstract depends on implementation. Because the parameters in the construction are all Human interfaces, so long as the implementation class of the Human can be passed in, it shows the structure of Decorator DT = new Decorator_second (new Decorator_first (new Decorator_zero (human)). So when dt.wearClothes();dt.walkToWhere() is called, and because each specific decorator class calls super.wearClothes and super.walkToWhere() methods first, and the super has been passed by the construct and pointed to a specific decorator class (this can be changed in order as needed), then the method of the decorator class is invoked, and then the method of the decorator class itself is invoked. Decorative method, that is, to show a decorative, chain-like behavior similar to filtering.
3. Specific decorated class, can define the initial state or the initial decoration of their own, the latter decorative behavior are based on this step by step to adorn, decoration.
4. The design principle of the decorator pattern is: open to expansion and close to modification. This sentence is reflected in the fact that if I want to expand the behavior of the decorated class, I need not modify the decorator Abstract class, only inherit the decorator Abstract class, and realize some additional decoration or behavior to package the decorated person. Therefore, expansion is embodied in inheritance and modification in subclasses rather than specific Abstract classes, which fully reflects the principle of inversion of dependence, which is the decorator model that I understand.


It's not clear what you're saying. Some people just feel that they can't express what they mean. Look at the code several times, then knock it out and run it on their own, and basically understand.


The following example also helps to understand the process and function of decoration.

Now you need a hamburger, the main body is chicken burger, you can choose to add lettuce, sauce, pepper and many other ingredients, in this case you can use the decorator mode.


Hamburg base class (decorated, equivalent to Hauman above)

  1. package decorator;    
  2.     
  3. public abstract class Humburger {    
  4.         
  5.     protected  String name ;    
  6.         
  7.     public String getName(){    
  8.         return name;    
  9.     }    
  10.         
  11.     public abstract double getPrice();    
  12.     
  13. }    
Chicken Leg Castle (the initial state of the decorated person, some of their own simple decoration, equivalent to the above Person)
  1. package decorator;    
  2.     
  3. public class ChickenBurger extends Humburger {    
  4.         
  5.     public ChickenBurger(){    
  6.         name = "Chicken burger";    
  7.     }    
  8.     
  9.     @Override    
  10.     public double getPrice() {    
  11.         return 10;    
  12.     }    
  13.     
  14. }    

Base of ingredients (decorator, used to decorate hamburgers in multiple layers, adding some ingredients to each layer, equivalent to the above Decorator)

  1. package decorator;    
  2.     
  3. public abstract class Condiment extends Humburger {    
  4.         
  5.     public abstract String getName();    
  6.     
  7. }    

 

Lettuce (decorator_zero on the first floor of the decorator)

  1. package decorator;    
  2.     
  3. public class Lettuce extends Condiment {    
  4.         
  5.     Humburger humburger;    
  6.         
  7.     public Lettuce(Humburger humburger){    
  8.         this.humburger = humburger;    
  9.     }    
  10.     
  11.     @Override    
  12.     public String getName() {    
  13.         return humburger.getName()+" Add lettuce";    
  14.     }    
  15.     
  16.     @Override    
  17.     public double getPrice() {    
  18.         return humburger.getPrice()+1.5;    
  19.     }    
  20.     
  21. }    


Chili pepper (decorator_first on the second floor of the decorator)

  1. package decorator;    
  2.     
  3. public class Chilli extends Condiment {    
  4.         
  5.     Humburger humburger;    
  6.         
  7.     public Chilli(Humburger humburger){    
  8.         this.humburger = humburger;    
  9.             
  10.     }    
  11.     
  12.     @Override    
  13.     public String getName() {    
  14.         return humburger.getName()+" Add chili";    
  15.     }    
  16.     
  17.     @Override    
  18.     public double getPrice() {    
  19.         return humburger.getPrice();  //Chili peppers are free.  
  20.     }    
  21.     
  22. }    


test class

  1. package decorator;    
  2.     
  3. public class Test {    
  4.     
  5.     /**  
  6.      * @param args  
  7.      */    
  8.     public static void main(String[] args) {    
  9.         Humburger humburger = new ChickenBurger();    
  10.         System.out.println(humburger.getName()+"  Price:"+humburger.getPrice());    
  11.         Lettuce lettuce = new Lettuce(humburger);    
  12.         System.out.println(lettuce.getName()+"  Price:"+lettuce.getPrice());    
  13.         Chilli chilli = new Chilli(humburger);    
  14.         System.out.println(chilli.getName()+"  Price:"+chilli.getPrice());    
  15.         Chilli chilli2 = new Chilli(lettuce);    
  16.         System.out.println(chilli2.getName()+"  Price:"+chilli2.getPrice());    
  17.     }    
  18.     
  19. }    

output

  1. Chicken Burger Price: 10.0
  2. Chicken Burger with Lettuce Price: 11.5
  3. Chicken Leg Castle with Chili Peppers Price: 10.0 ____________
  4. Chicken Burger, Lettuce and Pepper Price: 11.5


 

Author: Jason 0539

Micro-blog: http://weibo.com/2553717707

Blog: http://blog.csdn.net/jason0539 (Reprinted please indicate the source)

Posted by bckennyw on Mon, 15 Apr 2019 19:00:32 -0700