现在又这么一个场景
一家饭店经营多年后,终于开出了第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.动态的将责任附加到对象上,是区别于继承的另一种方式!
分享到:
相关推荐
7. 装饰模式:动态地给对象添加新的职责,而不影响其他对象,增强了系统的灵活性。 8. 适配器模式:使不兼容的接口能够协同工作,通过包装原有对象,提供新的接口给客户端。 9. 桥接模式:将抽象部分与实现部分分离...
结构型模式关心类和对象的组合,包括代理模式、装饰者模式、适配器模式、桥接模式、组合模式、外观模式和享元模式等。行为型模式关心类或对象怎样交互和怎样分配职责,包括模板方法模式、命令模式、责任链模式等。 ...
7. 装饰者模式(Decorator Pattern):动态的给一个对象添加一些额外的职责。 8. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口。 9. 桥接模式(Bridge Pattern):将抽象局部与实际...
结构型模式如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式和享元模式,关注的是如何将类和对象组合在一起,以形成更大的结构。行为型模式如策略模式、模板方法模式、观察者模式、迭代器模式、...
10. **装饰模式**:允许向一个现有的对象添加新的行为或责任,而无需改变其本质结构。 11. **外观模式**:为子系统提供了一个统一的接口,使得子系统更加容易使用。 12. **享元模式**:在不牺牲可扩展性的前提下,...
设计模式包括创建型模式(如单例、工厂方法、抽象工厂)、结构型模式(如适配器、装饰器、代理)和行为型模式(如策略、观察者、责任链)等。 2. **Java编程语言**:Java是一种广泛使用的面向对象的编程语言,以其...
- **装饰器模式**:动态地给一个对象添加一些额外的职责。 - **代理模式**:为其他对象提供一个代理以控制对这个对象的访问。 #### 3. 行为型模式 这类模式关注于对象之间的职责分配。常见的行为型模式有: - **...
装饰模式 外观模式 享元模式 代理模式 创建模式 抽象工厂模式 工厂方法模式 建造这模式 原型模式 单例模式 行为模式 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者...
- **装饰者模式**:动态地给一个对象添加一些额外的职责,提供比继承更灵活的替代方案。 - **适配器模式**:允许不兼容的接口协同工作。 - **桥接模式**:将抽象部分与其实现部分分离,使得两者可以独立变化。 -...
7. 装饰者模式(Decorator Pattern),动态地给一个对象添加一些额外的职责。 8. 适配器模式(Adapter Pattern),将一个类的接口转换成客户希望的另外一个接口。 9. 桥接模式(Bridge Pattern),将抽象部分与实现...
- 装饰模式(Decorator):动态地给对象添加一些额外的职责,增加功能而不改变原有结构。 - 外观模式(Facade):为子系统提供一个统一的接口,简化外部访问。 - 代理模式(Proxy):为其他对象提供一种代理以...
13. 装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责。就增加功能而言,装饰模式比生成子类更为灵活。 14. 迭代器模式(Iterator Pattern):提供一种方法顺序访问一个聚合对象中的各个元素,...
1. **设计模式讲义.doc、设计模式讲义.pdf**:这些文档很可能包含了课程的主要内容,包括设计模式的基本分类,如创建型、结构型和行为型模式,以及每种类型的代表模式如单例模式、工厂模式、适配器模式、装饰器模式...
这份资料详细地介绍了设计模式和软件体系结构的相关知识,适用于需要深入了解这两个领域的读者。...整体来看,这份资料对设计模式和软件体系结构进行了系统的梳理,有助于我们更好地理解这两个领域的知识。
- 装饰模式:动态地给一个对象添加一些额外的职责,提供比继承更具弹性的替代方案。 - 外观模式:提供一个统一的接口,用来访问子系统中的一组接口。 - 代理模式:为其他对象提供一种代理以控制对这个对象的访问...
### 面向对象与设计模式基础知识点梳理 #### 一、面向对象的基本概念 **面向对象编程(Object-Oriented Programming, OOP)** 是一种编程范式,其核心思想是将现实世界中的事物抽象成类(Class),并通过类创建...
5. 设计模式的类别包括但不限于工厂模式、单例模式、策略模式、观察者模式、装饰模式等,这些都是程序员应当熟练掌握的模式。 6. 文档提到了UML(统一建模语言)和API(应用程序编程接口)的重要性,这两者都是软件...