首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

设计方式-装饰器模式

2012-12-23 
设计模式----装饰器模式装饰器模式定义:动态地将责任附加到对象上,若要扩展功能,装饰器提供了比继承更有弹

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

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

上例子,咖啡店现有几种咖啡,超优深焙(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)模式一些问题

热点排行