设计模式-4-装饰者模式
2016-04-10 21:37
323 查看
1.装饰者模式概念
动态的将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
2.设计原则
1)封装变化
2)多用组合
3)针对接口编程,不针对实现编程
4)为交互对象之间松耦合设计而努力
5)对扩展开放,对修改关闭
3.举例对该模式的理解
星巴克咖啡店扩展迅速,需更新订单系统,为其设计合适的类:有多种咖啡此处举两个例子:Espresso、
HouseBlend;每种咖啡可选择加多种不同的调料,此处举例三种调料:Mocha(巧克力)、Soy(豆浆)、Whip(奶油)。每一种咖啡有本身的价格,加不同的调料相应添加不同的价格,设计合理的类,可以不需要修改代码而且可以动态的计算客人点的各种不同的咖啡价格(不修改代码的条件下,为类添加新的行为)。
思想:利用装饰者模式来实现,装饰者和被装饰者拥有相同的超类型,即这里的原始的咖啡(被装饰者)和调料(装饰者);拥有相同的超超类型,所以在任何需要原始对象的(被装饰者)的场合,都可以用装饰过的对象来替代他,装饰者可以在被装饰者的行为之前或之后加上自己的行为,已达到自己的目的(调料在之前的咖啡基础价格上加上自己的价格来实现客人点的各种价位不同的咖啡)。
4代码示例:
-----------------饮料超类型-------------------------
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
-----------------调料超类型-------------------------
/**
* 该类需要可以取代装饰者Beverage
* 故需要扩展自Beverage
* @author Lxt-PC
*
*/
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
-----------------原始咖啡1-------------------------
public class Espresso extends Beverage{
public Espresso() {
description = "Espresso";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.99;//只需关注自己的价格
}
}
-----------------原始咖啡2-------------------------
public class HouseBlend
extends Beverage{
public HouseBlend(){
description = "HouseBlend";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 2.22;//只需关注自己的价格
}
}
----------------调料1-------------------------
public
class Mocha extends CondimentDecorator{
//让Mocha能够引用一个Beverage 用一个实例变量
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.2+beverage.cost();
}
}
-----------------调料2-------------------------
public
class Soy extends CondimentDecorator{
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Soy";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return .8+beverage.cost();
}
}
-----------------调料3-------------------------
public
class Whip extends CondimentDecorator{
Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Whip";
}
@Override
public double cost() {
return .2+beverage.cost();
}
}
-----------------测试-------------------------
public
class StarbuzzCoffe {
public static void main(String[] args){
Beverage beverage = new Espresso();
beverage = new Whip(beverage);
System.out.println(beverage.getDescription()
+ "\t"
+ "$"+beverage.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()
+ "\t"
+ "$"+beverage2.cost());
}
}
-----------------测试结果-------------------------
Espresso,Whip
$2.19
HouseBlend,Mocha,Mocha,Whip $2.8200000000000007
动态的将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
2.设计原则
1)封装变化
2)多用组合
3)针对接口编程,不针对实现编程
4)为交互对象之间松耦合设计而努力
5)对扩展开放,对修改关闭
3.举例对该模式的理解
星巴克咖啡店扩展迅速,需更新订单系统,为其设计合适的类:有多种咖啡此处举两个例子:Espresso、
HouseBlend;每种咖啡可选择加多种不同的调料,此处举例三种调料:Mocha(巧克力)、Soy(豆浆)、Whip(奶油)。每一种咖啡有本身的价格,加不同的调料相应添加不同的价格,设计合理的类,可以不需要修改代码而且可以动态的计算客人点的各种不同的咖啡价格(不修改代码的条件下,为类添加新的行为)。
思想:利用装饰者模式来实现,装饰者和被装饰者拥有相同的超类型,即这里的原始的咖啡(被装饰者)和调料(装饰者);拥有相同的超超类型,所以在任何需要原始对象的(被装饰者)的场合,都可以用装饰过的对象来替代他,装饰者可以在被装饰者的行为之前或之后加上自己的行为,已达到自己的目的(调料在之前的咖啡基础价格上加上自己的价格来实现客人点的各种价位不同的咖啡)。
4代码示例:
-----------------饮料超类型-------------------------
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
-----------------调料超类型-------------------------
/**
* 该类需要可以取代装饰者Beverage
* 故需要扩展自Beverage
* @author Lxt-PC
*
*/
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
-----------------原始咖啡1-------------------------
public class Espresso extends Beverage{
public Espresso() {
description = "Espresso";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.99;//只需关注自己的价格
}
}
-----------------原始咖啡2-------------------------
public class HouseBlend
extends Beverage{
public HouseBlend(){
description = "HouseBlend";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 2.22;//只需关注自己的价格
}
}
----------------调料1-------------------------
public
class Mocha extends CondimentDecorator{
//让Mocha能够引用一个Beverage 用一个实例变量
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.2+beverage.cost();
}
}
-----------------调料2-------------------------
public
class Soy extends CondimentDecorator{
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Soy";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return .8+beverage.cost();
}
}
-----------------调料3-------------------------
public
class Whip extends CondimentDecorator{
Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Whip";
}
@Override
public double cost() {
return .2+beverage.cost();
}
}
-----------------测试-------------------------
public
class StarbuzzCoffe {
public static void main(String[] args){
Beverage beverage = new Espresso();
beverage = new Whip(beverage);
System.out.println(beverage.getDescription()
+ "\t"
+ "$"+beverage.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()
+ "\t"
+ "$"+beverage2.cost());
}
}
-----------------测试结果-------------------------
Espresso,Whip
$2.19
HouseBlend,Mocha,Mocha,Whip $2.8200000000000007
相关文章推荐
- 设计模式-3-工厂方法和抽象工厂模式
- 【Asp.net】初识
- 2016.4.10 线段树练习
- 20145120 《Java程序设计》第6周学习总结
- Atitit.跨语言异常转换机制 java c# php到js的异常转换
- [整理+原创]ubuntu Thunderbird Mail设置自动提醒
- Atitit.跨语言异常转换机制 java c# php到js的异常转换
- 组合数学 随记
- su和sudo命令
- 剑指Offer--008-旋转数组的最小数字
- jQuery点击按钮实现div的隐藏和显示切换效果
- 输出1-100之间的奇数
- struts2环境配置
- 手机抓包-fiddler
- Atitit.跨语言异常转换机制 java c# php到js的异常转换
- 如何选择恰当的图表类型(图表类型)
- Android下基于SDL的位图渲染(一)
- 支持不同的屏幕
- C语言printf
- CSS3_2D转换