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

设计模式----装饰器模式

阅读更多

装饰器模式定义:动态地将责任附加到对象上,若要扩展功能,装饰器提供了比继承更有弹性的替代方案

上例子,咖啡店现有几种咖啡,超优深焙(DarkRoast),无咖啡因咖啡(Decaf),浓咖啡(Espresso),有几种调料,牛奶(Milk),摩卡(Mocha),豆浆(Soy)

咖啡可以加任意调料,变化的可能有:咖啡种类,调料种类,调料价格

基于设计原则:类应该对扩展开放,对修改关闭,所以这些变化最好可以是动态去改变,这时候装饰器也就派上了用场

现上代码,再将原理:

 
/**
*  饮料,店内所有提供的饮料都必须继承此类
 */
public abstract class Beverage {
	String description = "Unknown Beverage";
  
	/**
	 * 由其子类描述饮料,例如:超优深焙(DarkRoast)
	 */
	public String getDescription() {
		return description;
	}
 
	/**
	 * 价格,子类必须定义自己的实现
	 */
	public abstract double cost();
}
 

 

/**
 *  调味装饰器
 */
public abstract class CondimentDecorator extends Beverage {
	public abstract String getDescription();
}
 

 

 

/**
 * 超优深焙
 */
public class DarkRoast extends Beverage {
	public DarkRoast() {
		description = "Dark Roast Coffee";
	}
 
	public double cost() {
		return .99;
	}
}

 

 

/**
 *  无咖啡因咖啡
 */
public class Decaf extends Beverage {
	public Decaf() {
		description = "Decaf Coffee";
	}
 
	public double cost() {
		return 1.05;
	}
}
 

 

 

 

/**
 *  浓咖啡
 */
public class Espresso extends Beverage {
  
	public Espresso() {
		description = "Espresso";
	}
  
	public double cost() {
		return 1.99;
	}
}
 

 

 

/**
 *  加牛奶
 */
public class Milk extends CondimentDecorator {
	Beverage beverage;

	public Milk(Beverage beverage) {
		this.beverage = beverage;
	}

	public String getDescription() {
		return beverage.getDescription() + ", Milk";
	}

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

 

 

 

/**
 *  摩卡
 */
public class Mocha extends CondimentDecorator {
	Beverage beverage;
 
	public Mocha(Beverage beverage) {
		this.beverage = beverage;
	}
 
	public String getDescription() {
		return beverage.getDescription() + ", Mocha";
	}
 
	public double cost() {
		return .20 + beverage.cost();
	}
}
 

 

 

 

/**
 *  豆浆
 */
public class Soy extends CondimentDecorator {
	Beverage beverage;

	public Soy(Beverage beverage) {
		this.beverage = beverage;
	}

	public String getDescription() {
		return beverage.getDescription() + ", Soy";
	}

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

 

 

/**
 *  覆盖奶泡
 */
public class Whip extends CondimentDecorator {
	Beverage beverage;
 
	public Whip(Beverage beverage) {
		this.beverage = beverage;
	}
 
	public String getDescription() {
		return beverage.getDescription() + ", Whip";
	}
 
	public double cost() {
		return .10 + beverage.cost();
	}
}
 

 

 

 

/**
 *  咖啡点测试类
 */
public class StarbuzzCoffee {
 
	public static void main(String args[]) {
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription() 
				+ " $" + beverage.cost());
 
		Beverage beverage2 = new DarkRoast();
		beverage2 = new Mocha(beverage2);
		beverage2 = new Mocha(beverage2);
		beverage2 = new Whip(beverage2);
		System.out.println(beverage2.getDescription() 
				+ " $" + beverage2.cost());
 
		Beverage beverage3 = new HouseBlend();
		beverage3 = new Soy(beverage3);
		beverage3 = new Mocha(beverage3);
		beverage3 = new Whip(beverage3);
		System.out.println(beverage3.getDescription() 
				+ " $" + beverage3.cost());
	}
}
 

OK,可以看出来装饰器的特点可有分为一下5个部分:

  • 装饰者和被装饰者对象有相同的超类(都继承Beverage)
  • 你可以用一个或者多个装饰者包装一个对象
  • 因为有相同超类,所以可以在anywhere and anytime 用装饰过的对象代替被装饰者,即可以在运行时动态地装饰对象
  • 装饰者可以在所委托的被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的----------装饰器模式的用途

总结:明白了装饰器,在来看java.io.*,似乎可以更好的理解了,所谓装饰就是继承共同父类,然后包装,变化其行为

那就再贴个自己实现java.io的装饰器,代码如下:

     

    /**
     *  将所有字节转换为小写
     */
    public class LowerCaseInputStream extends FilterInputStream {
    
    	public LowerCaseInputStream(InputStream in) {
    		super(in);
    	}
     
    	public int read() throws IOException {
    		int c = super.read();
    		//转换为小写
    		return (c == -1 ? c : Character.toLowerCase((char)c));
    	}
    		
    	public int read(byte[] b, int offset, int len) throws IOException {
    		int result = super.read(b, offset, len);
    		for (int i = offset; i < offset+result; i++) {
    		  //转换为小写
    			b[i] = (byte)Character.toLowerCase((char)b[i]);
    		}
    		return result;
    	}
    }

     

     

     

    /**
     *  io装饰器测试类
     */
    public class InputTest {
    	public static void main(String[] args) throws IOException {
    		int c;
    
    		try {
    			InputStream in = 
    				new LowerCaseInputStream(
    					new BufferedInputStream(
    						new FileInputStream("test.txt")));
    
    			while((c = in.read()) >= 0) {
    				System.out.print((char)c);
    			}
    
    			in.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }

     

     

    OK,至此装饰其模式结束,装饰器也有其缺点:

    1,加入大量的装饰类,如IO包一样,初看之时很是头晕,不过这点貌似没什么办法,有利就有弊嘛,呵呵。。。  

    2,增加了代码的难度,需要new很多对象,这点应该可以利用工厂(Factory)模式和生成器(Builder)模式一些问题

    分享到:
    评论

    相关推荐

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

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

      java常用设计模式-装饰器模式

      java常用设计模式-装饰器模式

      设计模式-装饰器模式

      ios平台中通过最简单的代码讲解装饰器模式,可在博客http://blog.sina.com.cn/s/blog_161d504630102wxis.html中查看简单解释

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

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

      设计模式课件大全

      设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...

      设计模式-C++

      结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...

      23种设计模式 -设计模式图解.7z

      结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...

      《C++20设计模式》学习笔记-第9章装饰器模式-配套代码

      《C++20设计模式》学习笔记-第9章装饰器模式-配套代码

      设计模式--C++

      1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...

      设计模式-访问者模式

      ios 平台实现设计模式-访问者模式,以最简单的代码实现访问者模式讲解,主旨在于了解访问者模式,博客:http://blog.sina.com.cn/s/blog_161d504630102wwxe.html

      23设计模式之装饰器模式-前端篇.pptx

      装饰模式 PPT 前端 javascript 讲解了装饰模式在前端的运用,举例说明,ppt内的代码连起来可执行

      设计模式-类图

      结构型模式 :适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式 行为型模式 :策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者...

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

      1.不改变原有对象的情况下给一个对象扩展功能 2.使用不同的组合可以实现不同的效果 3.符合开闭原则

      装饰工程-装饰工程系统-装饰工程系统源码-装饰工程管理系统-基于Web的装饰工程系统设计与实现-装饰工程系统设计与实现-java

      装饰工程-装饰工程系统-装饰工程系统源码-装饰工程管理系统-装饰工程管理系统java代码-装饰工程系统设计与实现-基于springboot的装饰工程系统-基于Web的装饰工程系统设计与实现-装饰工程网站-装饰工程网站代码-装饰...

      设计模式--可复用面向对象软件的基础

      1.2 Smalltalk MVC中的设计模式 1.3 描述设计模式 1.4 设计模式的编目 1.5 组织编目 1.6 设计模式怎样解决设计问题 1.7 怎样选择设计模式 1.8 怎样使用设计模式 第二章 实例研究:设计一个文档编辑器 2.1 设计问题...

      jouryfirst#weekly-1#175.精读《设计模式 - Decorator 装饰器模式》1

      “就增加功能来说,Decorator 模式相比生成子类更为灵活” 这句话的含义是,组合比继承更灵活,当可拓展的功能很多时,继承方案会产生大量的子类,而组合可以提

      装饰器设计模式

      控制访问,装饰器设计的四个名词,装饰器模式与代理模式的区别,

      研磨设计模式-part2

      《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    Global site tag (gtag.js) - Google Analytics