Decorator mode
preface
- I am a junior undergraduate majoring in software engineering. At present, we are preparing for internship and autumn recruitment. The intended position is java back-end development engineer. To this end, I hosted a project in codecloud to sort out all my knowledge. Contents involved: computer network, operating system, Java foundation, mainstream Java back-end framework, design pattern, Web front-end framework, etc. Welcome to my open source project The way of programming
- Code cloud address: https://gitee.com/alizipeng/the-way-of-programming
- The following contents are recorded in my open source project
1. Definitions
-
Dynamically attaching new functions to objects is decorator mode.
-
It embodies the opening and closing principle of the seven principles [OCP principle].
-
More extensible than inheritance.
2. Scene setting
Starbucks Coffee order project [Cafe]:
- Coffee type / single product: Espresso, ShortBlack, LongBlack, Decaf
- Seasoning: Milk, Soy Milk, Chocolate
- It is required to have good expansibility and maintainability when expanding new coffee varieties.
- Use object-oriented to calculate the cost of different kinds of coffee: customers can order single coffee or single coffee + seasoning combination.
3. Class structure design
3.1 Drink abstract class
/** * Beverage abstract class * * @author: zipeng Li * 2021/5/16 21:53 */ public abstract class Drink { /** * Beverage description */ private String description; /** * Price */ private Float price; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } /** * Calculate cost * @return */ public abstract Float cost(); }
3.2 Coffee class
/** * @author: zipeng Li * 2021/5/16 22:17 */ public class Coffee extends Drink { @Override public Float cost() { return super.getPrice(); } }
3.3 Decorator class
/** * Decorator * * @author: zipeng Li * 2021/5/16 22:41 */ public class Decorator extends Drink { Drink drink; public Decorator(Drink drink) { this.drink = drink; } @Override public Float cost() { return getPrice() + drink.cost(); } @Override public String getDescription() { return super.getDescription() + " Price:" + super.getPrice() + " && " + drink.getDescription(); } }
3.4 specific single coffee
Just list one of them, and other specific single coffee categories are similar.
/** * @author: zipeng Li * 2021/5/16 22:36 */ public class Decaf extends Coffee { public Decaf() { setDescription("decaf Price: 2.0"); setPrice(2.0f); } }
3.5 specific seasoning categories
Only one of them is listed, and other specific seasoning categories are similar.
/** * @author: zipeng Li * 2021/5/17 7:21 */ public class Chocolate extends Decorator { public Chocolate(Drink drink) { super(drink); setDescription("chocolate"); setPrice(1.0f); } }
3.6 test functional integrity
/** * @author: zipeng Li * 2021/5/17 7:23 */ public class Test { public static void main(String[] args) { // Start order // 1. Order a ShortBlack Drink drink = new ShortBlack(); System.out.println("Order Description:" + drink.getDescription()); System.out.println("Total cost:" + drink.cost()); // 2. Add a chocolate drink = new Chocolate(drink); System.out.println("Order Description:" + drink.getDescription()); System.out.println("Total cost:" + drink.cost()); // 3. Add two copies of soy drink = new Soy(drink); drink = new Soy(drink); System.out.println("Order Description:" + drink.getDescription()); System.out.println("Total cost:" + drink.cost()); } }
3.7 test scalability
Add a single coffee
/** * @author: zipeng Li * 2021/5/17 7:51 */ public class DIYCoffee extends Coffee { public DIYCoffee() { setDescription("DIYCoffee Price: 6.0"); setPrice(6.0f); } }
Order a DIYCoffee, the condiment remains the same
4. Application in JDK
In the IO system of Java, decorator mode is used:
- InputStream is an abstract class waiting to be decorated. Equivalent to the Drink class
- FileInputStream, StringBufferInputStream and ByteArrayInputStream are subclasses of InputStream, which are equivalent to specific single coffee classes
- FilterInputStream is a Decorator, equivalent to the Decorator class
- BufferInputStream, DataInputStream and LineNumberInputStream are specific decoration classes, which are equivalent to specific condiments