Today to write a decorator mode, the soft test, but also the internship, feel the mentality of quiet, design patterns are some simple small examples, but see so long even simple understanding has not been completely done, deeply ashamed, or to quiet down, the book only Yanruyu ~ ~ ~ Not to pull, the bottom into the topic
One, decorator pattern definitionBy dynamically extending the functionality of the original object without modifying the original class, the decorator provides a more resilient alternative to inheritance: wrapping real objects by creating a wrapper object (decorative object)Ii. Characteristics of the decorator pattern (1) The decorator and the decorator have the same super-type
(2) One or more decorators can be used to wrap an object(3) because the decorator and the decorator have the same super-type, you can replace it with a decorated object in any situation where the original object (the wrapped object) is needed.(4) the decorator May ,
before and/or after the act entrusted to the decorator , add his or her own behavior to achieve a specific purpose (note the bold part) (5) The object can be decorated at any time, so the object can be decorated dynamically and in an unlimited manner at run time with a decorator.Third, the concrete realization of the decorator pattern--Design the order management system of the coffee shop
1, first look at the coffee shop original class design:
Beverage Class (abstract Class): Attribute description set by subclass
Each subclass implements the cost abstraction method, returning the respective price
Of course, in the purchase of coffee, you can request to add a variety of spices: soy milk (Soy), Mocha (Mocha), milk Foam (Whip) and so on, the coffee shop will be based on the addition of spices to charge different fees, so the order system needs to consider these seasoning parts
Workaround (1): So we can do this and design these classes:
Mocha and milk foam deep-roasted coffee, mocha deep-roasted coffee, soy milk concentrate coffee, etc.
As you can see, we're going to have to use permutations and combinations to calculate how many classes we need based on the type of seasoning and coffee. It's a "class explosion" that creates a maintenance nightmare.
Workaround (2): redesign the beverage (beverage) class as follows
The redesigned beverage is no longer an abstract class but a concrete class:
public class Beverage { String description; Boolean milk; Boolean soy; Boolean Mocha; Boolean whip; Double milkcost = 1.0; Double soycost = 2.0; Double mochacost = 3.0; Double whipcost = 4.0; Get the description public String getdescription () { return description; } Get seasoning Price public double cost () { double condimentcost = 0.0; if (Ismilk ()) { Condimentcost + = Milkcost; } if (Ismocha ()) { Condimentcost + = Mochacost; } if (Issoy ()) { Condimentcost + = Soycost; } if (Iswhip ()) { Condimentcost + = Whipcost; } return condimentcost; } Omit milk, mocha, soy, whip setter and Getter methods}
then, implement the Darkroast (deep-roasted coffee Class):
public class Darkroast extends beverage {public darkroast () { Description = "I am a deep roasted coffee"; } public double Cost () { return 1.99+super.cost (); }}
then we write a main function:
public class Main {public static void Main (string[] args) { //I want a deep roasted coffee with milk t t = new T1 (); T.setmilk (true); System.out.println ("deep roasted coffee with milk price:" +t.cost ());} }
Print out results: deep-baked coffee with milk price: 2.99
In this way, we can achieve what we want. However, there is a very serious problem here: if we need to add a ingredient, we need to continue to modify this beverage class, which violates the "open
-closed design principle of extended open, modified closure ." How do we improve?
2. Reconstruct the system using the decorator mode
(1) If the customer wants mocha and milk foam deep-baked coffee, then what we need to do is
① take a deep roasted coffee object
② decorate it with a Mocha object
③ decorate it with a milk bubble object
④ calls the cost method and relies on the delegate to add the price of the spice up
Steps:
Wait until the money is counted, just call the outermost whip cost method to do it.
(2) Define decorator mode
3, using the decorator mode to achieve the coffee shop Order system:
Beverage.java
Public abstract class Beverage { protected String description = "Unknown beverage"; Public String getdescription () { return description; } public abstract double Cost ();}
Houseblend.java
Espresso public class Houseblend extends beverage {public houseblend () { Description = ' house Blend Coffee '; } Public double Cost () { return.; }}
Darkroast.java
Deep Bake coffee public class Darkroast extends beverage {public darkroast () { description = "Darkroast"; } public double Cost () { return.; }}
Epresso.java
Espresso public class Espresso extends beverage {public Espresso () { description = "Espresso"; } public double Cost () { return 1.99; }}
Condimentdecorator.java
The superclass public of the batching class is abstract class Condimentdecorator extends beverage {public abstract String getdescription ();
Mocha.java
Mocha (ingredient) public class Mocha extends Condimentdecorator { beverage beverage; Public Mocha (Beverage beverage) { this.beverage = beverage; } Public String getdescription () { return beverage.getdescription () + ", Mocha"; } public double Cost () { return. + beverage.cost (); }}
Soy.java
Soy milk (ingredients) public class Soy extends Condimentdecorator { beverage beverage; Public Soy (Beverage beverage) { this.beverage = beverage; } Public String getdescription () { return beverage.getdescription () + ", Soy"; } public double Cost () { return. + beverage.cost (); }}
Whip.java
Milk Foam (ingredient) public class Whip extends Condimentdecorator { beverage beverage; Public Whip (Beverage beverage) { this.beverage = beverage; } Public String getdescription () { return beverage.getdescription () + ", Whip"; } public double Cost () { return. + beverage.cost (); }}
Then write a simple main function:
public static void Main (string[] args) { beverage beverage = new Espresso (); System.out.println (beverage.getdescription () + "$" + beverage.cost ()); Beverage Beverage2 = new Darkroast (); Beverage2 = new Mocha (beverage2); Beverage2 = new Mocha (beverage2); Beverage2 = new Whip (beverage2); System.out . println (beverage2.getdescription () + "$" + beverage2.cost ()); Beverage Beverage3 = new Houseblend (); Beverage3 = new Soy (beverage2); Beverage3 = new Mocha (beverage2); Beverage3 = new Whip (beverage2); System.out . println (beverage3.getdescription () + "$" + beverage3.cost ());
"Design pattern" Headfirst design pattern (iii): Decorator (Decorator) mode