`
jiq408694711
  • 浏览: 36590 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

结构型-装饰器

 
阅读更多
package decorator;
/**
 * @author jiq
 * 类型:Structural
 * 定义:动态地将责任附加到对象上
 * 		若要拓展功能,装饰器提供了比继承更加有弹性的替代方案。
 * OO原则: 类应该 对修改关闭,对拓展开放!!! 
 * 
1 作用:
	对拓展开放,对修改关闭。
	避免继承滥用,学会使用组合,在运行时装饰类。

2 为什么要这么做呢?
	可以在不修改任何底层代码的情况下(<免于改变>),给你的(或者别人的)对象赋予新的职责(<易于拓展>)。
	这就是著名的“开放-关闭”原则: 类应当对拓展开放,对修改关闭。
	
3 实际用法:
	可见除了继承,装饰者模式也可以让我们拓展行为。
	装饰者模式意味着一群装饰者类,这些类用来包装具体的组件。
	你可以用无数装饰者来包装(组合)一个组件,而不需要更改任何原有的组件。
	
4 已有案例:
	Java IO流中的各种包装类就是典型的装饰者。 
 * *******************************************************
 * 类之间的关系:
	 * 组件抽象类:Beverage
	 * 装饰器抽象基类: CondimentDecorator 也继承自该抽象组件(为了迭代装饰)
	 * 
	 * 实际的Beverage(家用咖啡,特浓咖啡等)继承自该抽象组件 Beverage
	 * 各种装饰器(调料,大小等)继承自装饰器抽象基类CondimentDecorator
	 * 
	 * 用各种装饰器装饰实际的Beverage
 *
 * 如果只是用继承,每一种饮料都继承自Beverage,各种调料以及饮料的组合都需要一个类,这简直就是类爆炸!!!
 */
/**
 *  our company make beverage (组件基类)
 */
abstract class Beverage{
	protected String description = "unKown Beverage";
	public String getDescription(){
		return description;
	}
	/** calculate price of this beverage */
	public abstract double cost();
}

/**
 * Decorator(调料 - 装饰器基类)
 * 问题: 为什么装饰者还要从Beverage继承呢?
 * 为了能够使得具体的装饰器能够被其他装饰器装饰(拓展)。
 * 而装饰器只能装饰(拓展)Beverage。
 * */
abstract class CondimentDecorator extends Beverage{
	public abstract String getDescription();
}
///////////////////////////////////////////////////////////
//特浓咖啡(组件)
class Espresso extends Beverage{
	public Espresso(){description = "Espresso";}
	public double cost() {return 0.9;}
	
}

//家常咖啡(组件)
class HouseBlend extends Beverage{
	public HouseBlend(){description = "HouseBlend";	}
	public double cost() {return 1.0;}
	
}
///////////////////////////////////////////////////////////////
//用Mocha(装饰器)来装饰一杯beverage
class Mocha extends CondimentDecorator{
	Beverage beverage; //wrap a beverage(组合)	
	public Mocha(Beverage beverage){this.beverage = beverage;}
	
	public String getDescription() {
		return beverage.getDescription() + ", add Mocha";
	}

	public double cost() {
		return 0.20 + beverage.cost();
	}
}

//用豆浆(装饰器)来装饰一杯beverage
class Soy extends CondimentDecorator{
	Beverage beverage; //wrap a beverage(组合)
	
	public Soy(Beverage beverage){this.beverage = beverage;}
	
	public String getDescription() {
		return beverage.getDescription() + ", add Soy";
	}

	public double cost() {
		return 0.30 + beverage.cost();
	}	
}

public class Starbuzz {
	public static void main(String[] args) {
		/**
		 * 制造一杯Espresso咖啡,什么调料也不放
		 * */
		Beverage b1 = new Espresso();
		System.out.println(b1.getDescription() + " $" + b1.cost());
		
		/**
		 * 制造一杯HoseBlend咖啡,放入豆浆和摩卡
		 * */
		Beverage b2 = new HouseBlend();
		Beverage newBeverage = new Mocha(new Soy(b2));
		System.out.println(newBeverage.getDescription() + " $" + newBeverage.cost());
///////////////////////////////////////////////////////////////
		/**
		 * 思考:如果生成的饮料决定从今天开始加上容量大小。
		 * 		供顾客挑选大杯,中杯以及小杯,然后根据饮料容量
		 * 		来收费,我们应该怎么改变装饰者来应对这样的需求???
		 * 很显然,我们不能更改现有组件,因为我们的原则就是对修改关闭。
		 * 那怎么拓展呢??? 答案是增加一种装饰器。
		 * 装饰大小的装饰器,可以设置大小,更新价格。
		 * */		
		/**
		 * 制造一杯HoseBlend咖啡,放入豆浆,设置为中杯
		 * */
		Beverage b3 = new HouseBlend();
		Beverage b4 = new SizeDecorator(new Soy(b3), 1);	//设置大小
		System.out.println(b4.getDescription() + " $" + b4.cost());
		
		//是不是很爽啊?对修改关闭,对拓展任意开放
	}
}

/** 拓展一个设置饮料大小,并且根据大小计算价格的装饰器 */
class SizeDecorator extends CondimentDecorator{
	Beverage beverage; //wrap a beverage
	int size;	//拓展的属性	
	public SizeDecorator(Beverage beverage, int size){
		this.beverage = beverage;
		this.size = size;
	}
	
	//拓展的方法
	public void setSize(int size){	this.size = size; }
	
	//拓展的方法
	public int getSize(){ return size; }
	
	public String getDescription() {
		return beverage.getDescription() + ", set size:" + size;
	}

	public double cost() {
		return beverage.cost() * (0.5 + size/10); //根据大小计算价格
	}
}

分享到:
评论

相关推荐

    c++设计模式-结构型模式-装饰器模式

    c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

    设计模式-装饰器模式

    装饰器模式是一种结构型设计模式,它允许在不修改对象本身的情况下动态地为对象添加新的行为或职责。这种模式在软件工程中广泛应用,特别是在需要扩展已有功能而不影响原有代码结构时。在iOS开发中,装饰器模式同样...

    PHP设计模式(八)装饰器模式Decorator实例详解【结构型】

    装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...

    9.设计模式-装饰器模式1

    装饰器模式(Decorator Pattern)是一种结构型设计模式,它的核心思想是在不修改原有对象的前提下,通过包装(包裹)原对象并扩展其行为来增加功能。这种模式常用于在运行时动态地给对象添加新的职责,使得系统具有...

    54-Spring设计模式之装饰器模式1

    装饰器模式是一种结构型设计模式,它允许在不修改原有对象的情况下,动态地添加新的行为或功能。这种模式可以在不改变原有对象结构的情况下,添加新的功能。 装饰器模式实现 在 Spring 设计模式中,装饰器模式可以...

    Python 程序语言设计模式思路-结构型模式:装饰器讲解及利用Python装饰器模式实现高效日志记录和性能测试

    装饰器模式(Decorator Pattern)是结构型设计模式之一,用于动态地向对象添加额外的职责,而不影响其他对象。这种模式通过使用装饰器函数,允许你在保持原始功能的基础上,灵活地扩展代码的行为。

    设计模式2-结构型模式.doc

    在本文中,我们将探讨几种结构型设计模式,包括适配器模式、桥接模式、外观模式、享元模式、代理模式和装饰器模式。 1. **适配器模式**: - 适配器模式用于连接两个不兼容的接口,使得原本不能一起工作的类可以...

    软件体系结构---设计模式的java运行代码案例

    结构型模式如适配器(Adapter)、装饰器(Decorator)、代理(Proxy)和桥接(Bridge)等,关注如何组合和组装对象,使不同组件之间可以协同工作,增强系统的结构。 行为型模式如观察者(Observer)、策略...

    HeadFirst 设计模式学习笔记3--装饰模式 Demo

    装饰模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或责任,而无需修改对象的源代码。这种模式通常用于保持对象的原始类结构不变,同时增强其功能。HeadFirst 设计模式系列书籍以其生动有趣的插图和...

    19-decorators(装饰器19).pdf

    在类成员上,装饰器的执行顺序是:参数装饰器 -&gt; 方法装饰器/访问符装饰器/属性装饰器(按声明顺序),对于静态成员则类似,而构造函数的参数装饰器先于类装饰器执行。 在使用装饰器时,需要在编译选项中启用`...

    设计模式--装饰模式

    装饰模式(Decorator Pattern)是一种结构型设计模式,其主要目的是在不改变对象自身的基础上,在运行时为对象添加新的行为或属性。它通过包装原有对象,而不是通过继承来扩展功能,从而提供了更大的灵活性,避免了...

    [结构型模式] 装饰者模式的理解

    装饰者模式是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过动态地添加职责来扩展对象的功能。这种模式遵循开闭原则,即对扩展开放,对修改关闭,使得系统更易于维护和扩展。 在装饰者模式中,有四...

    设计模式 - 装饰模式(C++实例)

    装饰模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或责任,而无需修改对象的源代码。这种模式在软件工程中非常常见,因为它提供了灵活性,使得我们可以独立于对象的组合来扩展功能。 在C++中,装饰...

    设计模式之结构型模式

    在这个相亲的例子中,装饰者模式可以用来添加男人的描述,例如经济条件、性格特点等,这些描述可以独立于主体对象(男人)存在,通过装饰器累加,形成一个全面的个人形象。 4. **组合模式**: 组合模式允许我们...

    结构型模式之装饰模式(Decorator)

    装饰模式(Decorator)是软件设计模式中的一种结构型模式,其主要目的是在不改变对象原有类的基础上,通过添加新的行为或职责来扩展对象的功能。这种模式使得代码的扩展性非常优秀,避免了由于频繁地使用继承而导致...

    设计模式---装饰者模式

    装饰者模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码或创建子类。这种模式的核心思想是通过将对象封装在一个装饰器对象内,来扩展对象的功能,同时保持原有接口的不变...

    通过C#实现设计模式-装饰模式(DecoratorPattern).rar

    装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类,该类包装了原始类的实例,并在调用原始类方法之前或之后添加额外的...

    10-基于装饰器的日志写入器(1).html

    装饰器模式( Decorator ) 代理模式( Proxy ) 外观模式( Facade ) 桥接模式( Bridge ) 组合模式( Composite ) 享元模式( Flyweight ) 行为型模式包含了: 策略模式( Strategy ) 模板方法模式( ...

Global site tag (gtag.js) - Google Analytics