Head First 设计模式 --3 装饰者模式 开闭原则
装饰者模式:动态的将责任附加到对象上,若要扩展功能,装饰者提供了比集成更有弹性的替代方案。
设计原则:
1:封装变化
2:多用组合,少用继承
3:针对接口编程,不针对实现编程
4:为对象之间的松耦合设计而努力
5:对修改关闭,对扩展开放
用Head First 设计模式中的例子。
一个咖啡店,会有各种类型的咖啡,还会给咖啡加上各种辅料,计算价钱的时候当然要加上辅料的价钱。
显然,可能不可能为每一种可能性的咖啡都写一个方法。类似于这种问题,就可以用到装饰者模式类解决。
直接看代码
abstract class Beverage {
String description = "Unkwnown Beverage";
public String getDescripion() {
return description;
}
public abstract double cost();
}
abstract class CondimentDecorator extends Beverage {
public abstract String getDescripion();
}
class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
@Override
public double cost() {
return 1.00;
}
}
class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return 0.70;
}
}
class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescripion() {
return this.beverage.getDescripion() + ", Mocha";
}
@Override
public double cost() {
return 0.20 + beverage.cost();
}
}
public class Test {
public static void main(String[] args) {
Beverage beverage = new Espresso();
beverage = new Mocha(beverage);
beverage = new Mocha(beverage);
System.out.println(beverage.getDescripion() + "$" + beverage.cost());
}
}
类图:

这个例子上要表达的是什么意思?开始,咖啡只有一个cost方法,我们通过用装饰者模式给每种咖啡扩展了一个getDescription方法,同时又扩展了cost方法,现在这个cost方法是选择一个基础咖啡在继续加辅料把所有的钱加载一起。
设计原则:对修改关闭,对扩展开放(开闭原则)。
我们写代码的时候遵循设计原则固然是好的,但是不要为了遵循设计原则而去用设计原则,我们用这些原则的目的就是为了帮我们设计出更好代码,如果因为遵循了设计模式而让代码变的复杂,而且这个地方以后基本上也不会有什么扩展,那么就可以考虑不用这个设计模式。换句话说就是我们无法保证每个地方都应用设计模式,我们只需要在有可能改变的地方进行设计,而哪个是以后需要改变的地方,就看实际项目而定了。
还有一个之前说多的问题,组合优于继承,那么这个地方怎么还用到了继承。要明白,“组合优于继承”中的继承说的是利用集成获得了父类的行为(依赖继承)。而装饰者模式中用到的继承是未了让装饰者与被装饰者具有相同的类型(类型匹配),以便能让装饰者取代被装饰者。这里的行为来自装饰者(CondimentDecorator及其子类)和组件(各种咖啡)。如果是依赖继承,类的行为只能在编译时就决定。而装饰者模式可以在运行时,实现新的装饰者来增加新的行为。这里Beverage可以是一个抽象类,当然也可以设计成一个接口。
装饰者模式有能力为设计注入弹性,但是也有问题,上面的代码可以看到,会加入大量的类,而导致可能一般时候会看不懂。
Head First 设计模式 --3 装饰者模式 开闭原则的更多相关文章
- ZT 设计模式六大原则(6):开闭原则
ZT 设计模式六大原则(6):开闭原则 分类: 设计模式 2012-02-27 08:48 24870人阅读 评论(72) 收藏 举报 设计模式扩展框架编程测试 定义:一个软件实体如类.模块和函数应该 ...
- 【设计模式六大原则6】开闭原则(Open Close Principle)
定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不 ...
- 设计模式原则(6)--Open-Closed Principle(OCP)--开闭原则
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.定义: 一个软件实体应当对扩展开放,对修改关闭.即软件实体应尽量在不修改原有代码的情况下进行扩展. 2.使用场 ...
- 设计模式六大原则(六): 开闭原则(Open Closed Principle)
定义: 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来: 在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不 ...
- java设计模式学习笔记--开闭原则
基本介绍 1.开闭(ocp)原则时编程中最基础.最重要的设计原则 2.一个软件实体如类.木块和函数应该对扩展开放,对修改关闭.用抽象构建框架,用实现扩展细节.即对提供方开放,对使用方关闭. 3.当软件 ...
- 设计原则:开-闭原则(Open-Closed Principle, OCP)
开-闭原则就是软件实体应当对扩展开放,对修改关闭.(Software entities should be open for extension,but closed for modification ...
- 开闭原则(Open Closed Principle,OCP)
遵循开闭原则设计出的模块具有两个主要特征: 对于扩展是开放的(Open for extension).这意味着模块的行为是可以扩展的.当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的 ...
- php设计模式八-----装饰器模式
1.介绍: 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
- Java设计模式 - - 单例模式 装饰者模式
Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...
随机推荐
- 如何真正抓住微信小程序的红利? 阿禅知乎live总结
微信App定义 为满足用户某种开发需求.完全基于微信的消息或网页应用,入口是公众号,用户无需离开微信即可完成所有操作,所有需求都在公众号里被满足 微信App的优势 1. 顾客在哪里,就让顾客在哪里看到 ...
- 纯代码TableView自适应高度(很老的使用方法)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return ...
- grabcut
http://blog.csdn.net/zouxy09/article/details/8535087
- javascript中的真假值、数据类型判断以及+的特殊用法
一.javascript中的假值 jQuery中拥有一组数量奇大的假值,包括 0,NaN(非数),''(空字符串),false,null,undefined 这些值在if判断中全部等于假,但这些值彼此 ...
- 关于SqlParameter设定size和value
1.设定size 字段定义:column [Text] nvarchar(max) NULL 设定字段最大长度: new SqlParameter("@Text",SqlDbTyp ...
- AngularJS Best Practices: ui-router
ui-router is a 3rd-party module and is very powerful. It supports everything the normal ngRoute can ...
- 在Unity中如何取得一个Box的Bounds
private BoxCollider mCollider; // Use this for initialization void Start () { mCollider = GetCompone ...
- jQuery的扩展与noConflict
jQuery的扩展 noConflict
- java字符串相关
String类默认对equals方法进行了重写,比较的是字符串的字符,而非是object中equals方法默认的比较两个对象的内存地址
- ExtJs Grid 删除,编辑,查看详细等超链接处理
在网上查了好多资料,关于ExtJs处理操作栏的“删除”.“编辑”.“查看详细”的处理,原来项目都是这么处理: 操作栏:{ text:'操作', xtype:'actioncolumn', items ...