现在又这么一个场景
一家饭店经营多年后,终于开出了第100家房间,但是现在面临一个问题!就是菜单的更新,如果菜单中一个菜的更改的话,那么就需要更改所有的菜单。
简单的说家店有10本菜谱,那么100家就需要更新10*100,那是一个很恐怖的数据!
那怎么办呢,这个时候就需要设计一套电子菜单了!他们雇佣
了BigSoft公司的精英来开发这套系统!
好,项目就紧张的开始了,前期的需求调研,评估,UC的形成,架构的设计,详细设计。。。。
本来认为是一个很简单的系统,设计时碰到了一个问题!因为这家店有一道招牌菜---鸡。
这个鸡的性别可以分为 公鸡,母鸡。它们的价格是不一样的
但是这个鸡的来源又可以分为 中国产,日本产,不同产地的价格也是不一样的!
那这个菜单应该怎么设计呢。 是 鸡 ---- 中国公鸡,中国母鸡,日本公鸡,日本母鸡?
这样的话,将来又增加了来源美国鸡,若是鸡有了中性鸡呢?这些情况如何考虑?还是继续添加各种子类吗?
好吧!这个时候怎么办呢?伟大的BigSoft公司的精英们面对这点小问题当然是没问题了
就是采用了装饰模式,这里对于装饰模式的解释还是欠缺:
看代码;Chickren,就是被装饰的统一对象
package com.test.test.decoration;
public abstract class Chickren {
String desc;
/* empty implement
* @see com.test.test.decoration.Chickren#cost()
*/
public abstract int cost();
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
公鸡:
package com.test.test.decoration;
public class Cock extends Chickren {
public Cock(){
desc = "this is a cock,and it's price is $1.2";
}
@Override
public int cost() {
return 12;
}
}
母鸡:
package com.test.test.decoration;
public class Hen extends Chickren {
public Hen(){
desc = "this is a hen ";
}
@Override
public int cost() {
return 10;
}
}
装饰类:
package com.test.test.decoration;
public abstract class DecorationChickren extends Chickren{
public abstract String getDesc();
}
装饰者:
中国来的鸡
package com.test.test.decoration;
/**
* notice:
* price is 15$
* desc: a hen from guangdong province which is so beautiful ,and it price is just 15$.
* you just wait what ,come on baby !
* only one day, if you lost this time ,you will never forgive youself forever!
*
* @author inter12
*
*/
public class ChinaChickren extends DecorationChickren{
private volatile Chickren chickren; //这里声明为 volatile很关键!
public ChinaChickren(Chickren chickren){
this.chickren = chickren;
}
@Override
public int cost() {
return chickren.cost() + 15; //具体的调用方式
}
@Override
public String getDesc() {
return chickren.getDesc() + "and it's not a hen ! also a china chickren! ";
}
}
日本来的鸡:
package com.test.test.decoration;
/**
* price is $10
* desc :a chickren from japan,so delicious
* @author inter12
*
*/
public class JapanChickren extends DecorationChickren {
public Chickren chick; //注意,这里还是持有一个最初的父类接口,这样就可以做到随意的多级装饰
public JapanChickren(Chickren chick) {
this.chick = chick;
}
@Override
public String getDesc() {
return chick.getDesc()+"my god ,how delicious the chickren is!";
}
public int cost() {
return chick.cost() + 10;
}
}
购买的人来了:
package com.test.test.decoration;
public class ChickrenBuyer {
public static void main(String[] args) {
//调用方式一
// Chickren chickren = new Hen();
// chickren = new ChinaChickren(chickren);
//调用方式二
Chickren chickren = new ChinaChickren(new Hen());
System.out.println("price:" + chickren.cost());
System.out.println("desc:" + chickren.getDesc());
chickren = new JapanChickren(chickren);
System.out.println("price:" + chickren.cost());
System.out.println("desc:" + chickren.getDesc());
}
}
是不是很熟悉的看到了java.io中的组合方式呢
这里做的不好的是 每个装饰的子类都有持有一个 Chickren对象,准确的应该是装饰类持有一个chickren对象,调用父类的构造方法
只改造了装饰者部分即可
下面的是改造版本:
package com.test.test.decoration;
public abstract class DecorationChickren extends Chickren {
protected volatile Chickren chick;
public abstract String getDesc();
public DecorationChickren(Chickren chickren) {
this.chick = chickren;
}
public Chickren getChickren() {
return chick;
}
public void setChickren(Chickren chickren) {
this.chick = chickren;
}
}
具体的装饰l;
package com.test.test.decoration;
/**
* notice:
* price is 15$
* desc: a hen from guangdong province which is so beautiful ,and it price is just 15$.
* you just wait what ,come on baby !
* only one day, if you lost this time ,you will never forgive youself forever!
*
* @author inter12
*
*/
public class ChinaChickren extends DecorationChickren{
public ChinaChickren(Chickren chickren){
super(chickren);
}
@Override
public int cost() {
return chick.cost() + 15;
}
@Override
public String getDesc() {
return chick.getDesc() + "and it's not a hen ! also a china chickren! ";
}
}
日本鸡:
package com.test.test.decoration;
/**
* price is $10
* desc :a chickren from japan,so delicious
* @author inter12
*
*/
public class JapanChickren extends DecorationChickren {
public JapanChickren(Chickren chick) {
super(chick);
}
@Override
public String getDesc() {
return chick.getDesc()+"my god ,how delicious the chickren is!";
}
public int cost() {
return chick.cost() + 10;
}
}
总结:
1.适用于多维的系统,例如本案中就是个很经典例子。做菜,主料是鸡煲,鸡可以选择不同国家的鸡,鸡又可以采用不同的烧法,清蒸,红烧等。那么鸡和烧法就是两个维度,这样的情况下就可以猜装饰模式,在一个前提下,将不同的行为装饰上去。
2.语法结构上,一个抽象的主对象 一个抽象的装饰类,持有一个父类接口对象,所有继承装饰类的对象都必须持有父类接口引用,这样保证该继承路线的对象都能得到装饰!
3.装饰模式意味这一群装饰对象,并且反应了被装饰组件的类型。
4.装饰者会导致设计中出现许多小对象,如果过度使用,会让系统变的很复杂!
5.动态的将责任附加到对象上,是区别于继承的另一种方式!
分享到:
相关推荐
财富管理研究系列一,全球财富管理发展历程及模式梳理.pdf
物联网通信模式梳理.xlsx
校企合作模式梳理.ppt
垃圾分类上海模式下市场规模梳理.rar
违约那些事儿:18年民企违约模式全梳理-国泰君安-20190125.pdf
Java设计模式整体梳理概览图
XX省灵宝企业项目架构模式梳理(doc 74) .doc
特色小镇产业投资基金设立模式梳理(下篇).doc
计算机行业AIGC投资机会梳理:ChatGPT快速流行,重构AI商业模式.zip计算机行业AIGC投资机会梳理:ChatGPT快速流行,重构AI商业模式.zip计算机行业AIGC投资机会梳理:ChatGPT快速流行,重构AI商业模式.zip计算机行业...
本文来自51cto,文章主要介绍了策略模式、观察者模式、装饰模式、单例模式以及饿汉模式等的相关内容。泛化=实现>组合>聚合>关联>依赖一个人(Person)可以买车(car)和房子(House),那么就可以称:Person类依赖于Car类...
<并行计算架构与模式>课程知识结构梳理, 采用思维导图右向图模式, 类似考研复习全书每章前面的知识图谱, 全面且清晰, 是花了大工夫复习总结出来的
民企违约模式全梳理:违约那些事儿-0125-国泰君安-16页.pdf
QuickSettings流程梳理
华为流程梳理与优化咨询项目方法论 华为流程梳理和流程优化解决方案 工作步骤及关键工作内容 项目价值 项目组织、时间计划与工作分工
StatusBar流程梳理-F
商品sku梳理简述.doc
管理方法及案例相结合,供您在做数据资产梳理的时候参考。可用性强。
App安全合规的思考(二) 监管的重点变化梳理.pdfApp安全合规的思考(二) 监管的重点变化梳理.pdfApp安全合规的思考(二) 监管的重点变化梳理.pdfApp安全合规的思考(二) 监管的重点变化梳理.pdfApp安全合规的思考(二) ...
数据安全治理三步走之一:数据资产状况梳理.docx数据安全治理三步走之一:数据资产状况梳理.docx数据安全治理三步走之一:数据资产状况梳理.docx数据安全治理三步走之一:数据资产状况梳理.docx数据安全治理三步走之...