设计模式-Python Java装饰者模式
2015-05-19 15:01
441 查看
装饰者模式定义
动态地将责任附加到对象上。若要扩展功能,装饰者提供比继承更有弹性的替代方案实现类图
装饰者模式的特点
A 装饰者和被装饰对象有相同的超类型。(注意这是利用继承达到”类型匹配“,而不是利用继承获得”行为“,行为来自装饰者和基础组件,或者与其他装饰者之间的组合关系)B 可以用一个或多个装饰者包装一个对象。
C 因为装饰者和被装饰者具有相同的类型,所以任何需要原始对象的场合,可以用装饰过的对象代替。
D 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
E 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象
装饰者模式实现例子
例子1interface Widget { void draw(); } // 1. "lowest common denominator" class TextField implements Widget { // 3. "Core" class with "isa" rel private int width, height; public TextField( int w, int h ) { width = w; height = h; } public void draw() { System.out.println( "TextField: " + width + ", " + height ); } } // 2. Second level base class abstract class Decorator implements Widget { // with "isa" relationship private Widget wid; // 4. "hasa" relationship public Decorator( Widget w ) { wid = w; } public void draw() { wid.draw(); } // 5. Delegation } class BorderDecorator extends Decorator { // 6. Optional embellishment public BorderDecorator( Widget w ) { super( w ); } public void draw() { super.draw(); // 7. Delegate to base class System.out.println( " BorderDecorator" ); // and add extra stuff } } class ScrollDecorator extends Decorator { // 6. Optional embellishment public ScrollDecorator( Widget w ) { super( w ); } public void draw() { super.draw(); // 7. Delegate to base class System.out.println( " ScrollDecorator" ); // and add extra stuff } } //装饰者可以在所委托被装饰者的行为之前或者之后,加上自己的行为,以达到特定的目的 public class DecoratorDemo { public static void main( String[] args ) { // 8. Client has the responsibility to compose desired configurations Widget aWidget = new BorderDecorator( new BorderDecorator( new ScrollDecorator( new TextField( 80, 24 )))); aWidget.draw(); } }
输出结果为:TextField: 80, 24
ScrollDecorator
BorderDecorator
BorderDecorator
对比python装饰模式实现的一个类似程序
def bread(func): def wrapper(): print "</''''''\>" func() print "<\______/>" return wrapper def ingredients(func): def wrapper(): print "#tomatoes#" func() print "~salad~" return wrapper @bread @ingredients def sandwich(food="--ham--"): print food if (__name__=="__main__"): sandwich()
[b]例子2:编写自己的java I/O装饰器,能够实现将文本中的大写字母转换成小写[/b]
JAVA I/O类就是利用装饰者模式来实现诸多的读取方式,InputStream是装饰者中的抽象组件。FilterInputStream是一个抽象装饰者,LIneNumberInputStream是一个具体装饰者,加上了计算行数的能力,BufferInputStream是一个加上缓冲输入功能和readline()方法的具体装饰者
import java.io.*; class LowerCaseInputStream extends FilterInputStream{ public LowerCaseInputStream (InputStream in) { super(in); } //必须实现两个read方法 一个针对字节 一个针对字节数组 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; } } public class InputTest { public static void main(String[] args) { 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(); } }
[b]例3:编写实现不同种类咖啡加上不同配料的计价程序[/b]
//抽象组件饮料 abstract class Beverage { String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract double cost(); } //具体组件 一种咖啡 class Espresso extends Beverage { public Espresso() { description = "Espresso"; } public double cost() { return 1.99; } } class DarkRoast extends Beverage { public DarkRoast() { description = "Dark Roast Coffee"; } public double cost() { return .99; } } class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } public double cost() { return .89; } } //装饰者抽象类 public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); } //具体装饰者牛奶 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(); } } //具体装饰者摩卡 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(); } } //具体装饰者奶泡 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()); } }
相关文章推荐
- java软件体系结构设计模式----装饰者
- Java 装饰者设计模式
- Java设计模式:装饰者模式(Decorator)
- 设计模式:装饰者模式(Python)
- Head First Java 设计模式——装饰者模式
- java设计模式之装饰者模式
- 设计模式之三:装饰者模式(java内置)
- 【Java设计模式】装饰者模式
- Java设计模式之装饰者模式
- java设计模式---装饰者模式(简单笔记)
- java设计模式---装饰者模式(简单笔记)
- JAVA设计模式——装饰者模式
- Java设计模式之装饰者模式
- JAVA设计模式——装饰者模式
- java 设计模式中 装饰者模式 与 代理模式的区别
- JAVA系列-设计模式-装饰者模式
- java设计模式之装饰者模式
- java 设计模式 学习笔记(三)装饰者模式 推荐
- Java 设计模式 装饰者模式
- Java 设计模式 装饰者模式