02.裝飾者模式
1镜悉、認(rèn)識裝飾者模式
購買咖啡時(shí)祟辟,除了咖啡的各種口味以外,還可以加入各種調(diào)料侣肄,例如:蒸奶旧困、豆?jié){、摩卡或奶蓋稼锅,星巴克會(huì)根據(jù)加入不同的調(diào)料收取不同的費(fèi)用吼具,當(dāng)然還有大中小杯等等。
如果我們使用類繼承的方式缰贝,會(huì)導(dǎo)致類數(shù)目爆炸馍悟、設(shè)計(jì)死板,以及基類加入的新功能并不適用于所有的子類剩晴。
所以我們要采取不一樣的做法锣咒,我們以飲料為主體,然后采用調(diào)料類赞弥、體積類來修飾毅整。
(1)拿一個(gè)深焙咖啡(DarkRoast)對象
(2)以摩卡(Mocha)對象來修飾
(3)以奶泡(Whip)來修飾
(4)以中杯(Medium)來修飾
(5)調(diào)用cost()方法,并依賴委托(delegate)將調(diào)料的價(jià)錢加上
2绽左、定義
裝飾者模式:動(dòng)態(tài)地將責(zé)任附加到對象上悼嫉,若要拓展功能,裝飾者提供了比繼承更有彈性的替代方案拼窥。
3戏蔑、設(shè)計(jì)原則:
開放-關(guān)閉原則
類應(yīng)該對擴(kuò)展開放,對修改關(guān)閉鲁纠。
我們的目標(biāo)是允許類容易拓展总棵,在不修改現(xiàn)有代碼的情況下,就可搭配新的行為改含。
4情龄、設(shè)計(jì)
代碼實(shí)現(xiàn):
(1)裝飾者總抽象類
public abstract class Beverage {
public String description = "Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
(2)調(diào)料裝飾者 抽象類
public abstract class CondimentDecorator extends Beverage {
@Override
public abstract String getDescription();
}
(3)容量裝飾者 抽象類
public abstract class Capacity extends Beverage {
@Override
public abstract String getDescription();
}
(4)四種咖啡實(shí)現(xiàn)類
/**
* 深度烘焙咖啡類
*/
public class DarkRoast extends Beverage {
public DarkRoast(){
this.description = "DarkRoast";
}
@Override
public double cost() {
return 2.99;
}
}
/**
* 貓屎咖啡
*/
public class Decat extends Beverage {
public Decat(){
this.description = "Decat";
}
@Override
public double cost() {
return 1.89;
}
}
/**
* 濃縮咖啡類
*/
public class Espresso extends Beverage {
public Espresso(){
this.description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
/**
* 首選咖啡(星巴克咖啡名)
*/
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
(5)調(diào)料類
/**
* 摩卡 調(diào)料類
*/
public class Mocha extends CondimentDecorator {
private Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Mocha";
}
@Override
public double cost() {
return .20 + beverage.cost();
}
}
/**
* 大豆 調(diào)料類
*/
public class Soy extends CondimentDecorator {
private Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Soy";
}
@Override
public double cost() {
return .30 + beverage.cost();
}
}
/**
* 鮮奶 調(diào)料類
*/
public class Whip extends CondimentDecorator {
private Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Whip";
}
@Override
public double cost() {
return .50 + beverage.cost();
}
}
(6)容量類
/**
* 大杯
*/
public class Big extends Capacity {
private Beverage beverage;
public Big(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return beverage.cost() + 0.20;
}
@Override
public String getDescription() {
return beverage.getDescription() + " ,Big";
}
}
/**
* 中杯
*/
public class Medium extends Capacity {
private Beverage beverage;
public Medium(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return beverage.cost() + 0.15;
}
@Override
public String getDescription() {
return this.beverage.getDescription() + " ,Medium";
}
}
/**
* 小杯
*/
public class Small extends Capacity {
private Beverage beverage;
public Small(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return beverage.cost() + 0.10;
}
@Override
public String getDescription() {
return this.beverage.getDescription() + " ,Small";
}
}
(7)測試類
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
Beverage beverage1 = new DarkRoast();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Whip(beverage1);
System.out.println(beverage1.getDescription() + " $" + beverage1.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Soy(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
beverage2 = new Big(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
}
}
結(jié)果:
Espresso $1.99
DarkRoast,Mocha,Mocha,Whip $3.8900000000000006
HouseBlend,Soy,Mocha,Whip ,Big $2.09
1、認(rèn)識裝飾者模式
購買咖啡時(shí)捍壤,除了咖啡的各種口味以外骤视,還可以加入各種調(diào)料,例如:蒸奶鹃觉、豆?jié){专酗、摩卡或奶蓋,星巴克會(huì)根據(jù)加入不同的調(diào)料收取不同的費(fèi)用帜慢,當(dāng)然還有大中小杯等等笼裳。
如果我們使用類繼承的方式唯卖,會(huì)導(dǎo)致類數(shù)目爆炸粱玲、設(shè)計(jì)死板躬柬,以及基類加入的新功能并不適用于所有的子類。
所以我們要采取不一樣的做法抽减,我們以飲料為主體允青,然后采用調(diào)料類、體積類來修飾卵沉。
(1)拿一個(gè)深焙咖啡(DarkRoast)對象
(2)以摩卡(Mocha)對象來修飾
(3)以奶泡(Whip)來修飾
(4)以中杯(Medium)來修飾
(5)調(diào)用cost()方法颠锉,并依賴委托(delegate)將調(diào)料的價(jià)錢加上
2、定義
裝飾者模式:動(dòng)態(tài)地將責(zé)任附加到對象上史汗,若要拓展功能琼掠,裝飾者提供了比繼承更有彈性的替代方案。
3停撞、設(shè)計(jì)原則:
開放-關(guān)閉原則
類應(yīng)該對擴(kuò)展開放瓷蛙,對修改關(guān)閉。
我們的目標(biāo)是允許類容易拓展戈毒,在不修改現(xiàn)有代碼的情況下艰猬,就可搭配新的行為。
4埋市、設(shè)計(jì)
代碼實(shí)現(xiàn):
(1)裝飾者總抽象類
public abstract class Beverage {
public String description = "Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
(2)調(diào)料裝飾者 抽象類
public abstract class CondimentDecorator extends Beverage {
@Override
public abstract String getDescription();
}
(3)容量裝飾者 抽象類
public abstract class Capacity extends Beverage {
@Override
public abstract String getDescription();
}
(4)四種咖啡實(shí)現(xiàn)類
/**
* 深度烘焙咖啡類
*/
public class DarkRoast extends Beverage {
public DarkRoast(){
this.description = "DarkRoast";
}
@Override
public double cost() {
return 2.99;
}
}
/**
* 貓屎咖啡
*/
public class Decat extends Beverage {
public Decat(){
this.description = "Decat";
}
@Override
public double cost() {
return 1.89;
}
}
/**
* 濃縮咖啡類
*/
public class Espresso extends Beverage {
public Espresso(){
this.description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
/**
* 首選咖啡(星巴克咖啡名)
*/
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
(5)調(diào)料類
/**
* 摩卡 調(diào)料類
*/
public class Mocha extends CondimentDecorator {
private Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Mocha";
}
@Override
public double cost() {
return .20 + beverage.cost();
}
}
/**
* 大豆 調(diào)料類
*/
public class Soy extends CondimentDecorator {
private Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Soy";
}
@Override
public double cost() {
return .30 + beverage.cost();
}
}
/**
* 鮮奶 調(diào)料類
*/
public class Whip extends CondimentDecorator {
private Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Whip";
}
@Override
public double cost() {
return .50 + beverage.cost();
}
}
(6)容量類
/**
* 大杯
*/
public class Big extends Capacity {
private Beverage beverage;
public Big(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return beverage.cost() + 0.20;
}
@Override
public String getDescription() {
return beverage.getDescription() + " ,Big";
}
}
/**
* 中杯
*/
public class Medium extends Capacity {
private Beverage beverage;
public Medium(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return beverage.cost() + 0.15;
}
@Override
public String getDescription() {
return this.beverage.getDescription() + " ,Medium";
}
}
/**
* 小杯
*/
public class Small extends Capacity {
private Beverage beverage;
public Small(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return beverage.cost() + 0.10;
}
@Override
public String getDescription() {
return this.beverage.getDescription() + " ,Small";
}
}
(7)測試類
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
Beverage beverage1 = new DarkRoast();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Whip(beverage1);
System.out.println(beverage1.getDescription() + " $" + beverage1.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Soy(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
beverage2 = new Big(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
}
}
結(jié)果:
Espresso $1.99
DarkRoast,Mocha,Mocha,Whip $3.8900000000000006
HouseBlend,Soy,Mocha,Whip ,Big $2.09