【先吃三颗栗子:】
1.pc=主机+显示器+键盘+鼠标+鼠标垫
主机是核心,而其他的组成部分都是装饰。
2.手抓饼=饼+鸡蛋+培根+黄瓜
饼是核心,鸡蛋,培根是可选的,可以理解为装饰。
3.咖啡=咖啡+牛奶+冰+方糖
咖啡是核心,牛奶等可选。
比喻虽然形象生动,但是与实际或多或少会产生偏差。
抽象的解释:装饰器模式的目的——核心部分和装饰部分可以自由组合。
对于软件开发来说,聚焦于软件的灵活性和可扩展性。
装饰器模式要求:
实现饼加各种配料的价格计算。
思路:
1.定义抽象类手抓饼,其中包含获取种类的抽象方法和获取价格的抽象方法。
2.然后定义两个分别为大份手抓饼和中份手抓饼来继承这个抽象类,重写两个方法定义种类和价格。
3.定义具体的配料类继承手抓饼抽象类,先定义构造器传入已经创建的手抓饼种类,然后重写种类和价格方法。
在网上看的一些博客,是创建出一个抽象的配料类来继承抽象产品类,然后用具体的配料类来实现抽象配料类,实现装饰。
可是如果直接将抽象产品类的方法全部定义抽象方法,配料类直接继承重写,实现装饰,功能上也是可以实现的,如下所示,bacon类直接继承handpancake,然后重写getname和getcost方法,实现装饰。似乎也没有问题:
但是设计模式毕竟是一种经验总结,如果有已经看出端倪的小伙伴们在下方留言交流一下吧!
直接继承handpancake:
abstract class handpancake { public abstract string getname(); public abstract int getcost(); } class handpancake_big extends handpancake { @override public string getname() { return "大份手抓饼"; } @override public int getcost() { return 10; } } class handpancake_mid extends handpancake { @override public string getname() { return "中份手抓饼"; } @override public int getcost() { return 8; } } class bacon extends handpancake { private handpancake handpancake; bacon(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加培根"; } @override public int getcost() { return handpancake.getcost()+1; } } class cucumber extends handpancake { private handpancake handpancake; cucumber(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加黄瓜"; } @override public int getcost() { return handpancake.getcost()+2; } } class ham extends handpancake { private handpancake handpancake; ham(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加火腿"; } @override public int getcost() { return handpancake.getcost()+1; } } public class application { public static void main(string[] args) { handpancake handpancake_big = new handpancake_big(); system.out.println("啥也不加"+handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new ham(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new cucumber(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new bacon(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); system.out.println("=============================="); handpancake handpancake_mid = new handpancake_mid(); system.out.println("啥也不加"+handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new ham(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new cucumber(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new bacon(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); } }
官方做法:
abstract class handpancake { string name; //1 public string getname() { return name; } public abstract int getcost(); } class handpancake_big extends handpancake { handpancake_big() //2.通过构造器赋值 { name="大份手抓饼"; } @override public int getcost() { return 10; } } class handpancake_mid extends handpancake { handpancake_mid() //2.通过构造器赋值 { name="中份手抓饼"; } @override public int getcost() { return 8; } } abstract class condiments extends handpancake //3.定义抽象接口 { public abstract string getname(); } class bacon extends condiments //4.继承抽象接口 { private handpancake handpancake; bacon(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加培根"; } @override public int getcost() { return handpancake.getcost()+1; } } class cucumber extends condiments { private handpancake handpancake; cucumber(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加黄瓜"; } @override public int getcost() { return handpancake.getcost()+2; } } class ham extends condiments { private handpancake handpancake; ham(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加火腿"; } @override public int getcost() { return handpancake.getcost()+1; } } public class application { public static void main(string[] args) { handpancake handpancake_big = new handpancake_big(); system.out.println("啥也不加"+handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new ham(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new cucumber(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new bacon(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); system.out.println("=============================="); handpancake handpancake_mid = new handpancake_mid(); system.out.println("啥也不加"+handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new ham(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new cucumber(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new bacon(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); } }
官方的扩展:创建一个小份手抓饼继承hanpancake,然后创建配料继承condiments。
贴一下直接继承handpancake的情况:
class handpancake_smalll extends handpancake
class egg extends handpancake
abstract class handpancake { public abstract string getname(); public abstract int getcost(); } class handpancake_big extends handpancake { @override public string getname() { return "大份手抓饼"; } @override public int getcost() { return 10; } } class handpancake_mid extends handpancake { @override public string getname() { return "中份手抓饼"; } @override public int getcost() { return 8; } } class bacon extends handpancake { private handpancake handpancake; bacon(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加培根"; } @override public int getcost() { return handpancake.getcost()+1; } } class cucumber extends handpancake { private handpancake handpancake; cucumber(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加黄瓜"; } @override public int getcost() { return handpancake.getcost()+2; } } class ham extends handpancake { private handpancake handpancake; ham(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加火腿"; } @override public int getcost() { return handpancake.getcost()+1; } } //======================== class handpancake_smalll extends handpancake { @override public string getname() { return "小份手抓饼"; } @override public int getcost() { return 5; } } class egg extends handpancake { private handpancake handpancake; egg(handpancake handpancake) { this.handpancake=handpancake; } @override public string getname() { return handpancake.getname()+"加鸡蛋"; } @override public int getcost() { return handpancake.getcost()+1; } } public class application { public static void main(string[] args) { handpancake handpancake_big = new handpancake_big(); system.out.println("啥也不加"+handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new ham(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new cucumber(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); handpancake_big = new bacon(handpancake_big); system.out.println(handpancake_big.getname()+":"+handpancake_big.getcost()); system.out.println("=============================="); handpancake handpancake_mid = new handpancake_mid(); system.out.println("啥也不加"+handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new ham(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new cucumber(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); handpancake_mid = new bacon(handpancake_mid); system.out.println(handpancake_mid.getname()+":"+handpancake_mid.getcost()); system.out.println("扩展性测试:"); handpancake handpancake_small = new handpancake_smalll(); system.out.println("啥也不加"+handpancake_small.getname()+":"+handpancake_small.getcost()); handpancake_small = new egg(handpancake_small); system.out.println(handpancake_small.getname()+":"+handpancake_small.getcost()); } }
运行结果:
如对本文有疑问, 点击进行留言回复!!
【面试题】研究过tomcat的NioEndpoint源码吗?请阐述下Reactor多线程模型在tomcat中的实现。
荐 厉害了!阿里P8架构师用4大技术文档带你深入解读爆火的中台战略
网友评论