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

星巴兹咖啡准备更新订单系统,为的是不违背开放-关闭的设计原则:类应该对扩展开放,对修改关闭。

我们的目标是允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。

这个目标需要使用装饰者模式实现:以饮料为主体,然后运行调料来“装饰”饮料。

1.定义装饰者模式
装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更具有弹性的替代方案。
 装饰者模式类图

Head First 设计模式--装饰者模式_第1张图片

2.把星巴兹咖啡系统进行修改,使其符合装饰者类图:

Head First 设计模式--装饰者模式_第2张图片

3.具体实现:

从饮料下手,将饮料作为一个抽象类:

package com.wk.cafe;

public abstract class Beverage {
	String description = "Unkown Beverage";
	
	public String getDescription(){
		return description;
	}
	
	public abstract double cost();
}
调料抽象类,也就是装饰者类:

package com.wk.cafe;

public abstract class CondimentDecorator extends Beverage{
	public abstract String getDescription();
	
}
实现具体的饮料:

package com.wk.cafe;

public class Espresso extends Beverage {
	public Espresso(){
		description = "Espresso";
	}

	public double cost(){
		return 1.99;
	}
}

package com.wk.cafe;

public class HouseBlend extends Beverage {  
    public HouseBlend() {  
        description = "HouseBlend";  
    }  
  
    public double cost() {  
        return 0.89;  
    }  
}  
实现具体装饰者类:

package com.wk.cafe;

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 0.20+beverage.cost();
	}
}


package com.wk.cafe;

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 0.20+beverage.cost();
	}
}
package com.wk.cafe;

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 0.20+beverage.cost();
	}
}
测试代码:

package com.wk.cafe;

public class StartbuzzCoffee {  
    public static void main(String args[]) {  
        Beverage beverage1 = new Espresso();  
        System.out.println(beverage1.getDescription() + "  $"  
                + beverage1.cost());  
        
        beverage1 = new Mocha(beverage1);
        beverage1 = new Whip(beverage1);
        System.out.println(beverage1.getDescription() + "  $"  
                + beverage1.cost());  
        
        Beverage beverage2 = new HouseBlend();  
        beverage2 = new Soy(beverage2);  
        beverage2 = new Mocha(beverage2);  
        beverage2 = new Whip(beverage2);  
        System.out.println(beverage2.getDescription() + "  $"  
                + beverage2.cost());  
    }  
  
} 
测试结果:

Head First 设计模式--装饰者模式_第3张图片


 JAVA中的装饰者模式(java.io类):

Head First 设计模式--装饰者模式_第4张图片

Java I/O引出装饰者模式的一个“缺点”:利用装饰者模式,会造成设计中存在大量的小类。

我们可以编写自己的Java I/O装饰者(即ConcreteDecorator),它的作用是把输入流中的所有小写字母转成大写:

代码如下:

package com.wk.cafe;

import java.io.FilterInputStream;  
import java.io.IOException;  
import java.io.InputStream;  
  
public class UpperCaseInputStream extends FilterInputStream {  
  
    protected UpperCaseInputStream(InputStream in) {  
        super(in);  
        // TODO Auto-generated constructor stub  
    }  
  
    public int read() throws IOException {  
        int c = super.read();  
        return (c == -1 ? c : Character.toUpperCase((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.toUpperCase((char) b[i]);  
        }  
        return result;  
    }  
}  

对刚刚写好的I/O装饰者进行测试:

package com.wk.cafe;

import java.io.*;  

public class UpperCaseInputStreamTest {  
    public static void main(String[] args) throws IOException {  
        int c;  
  
        try {  
            InputStream in = new UpperCaseInputStream(new BufferedInputStream(  
                    new FileInputStream("E:\\inputtest.txt")));  
  
            while ((c = in.read()) >= 0) {  
                System.out.print((char) c);  
            }  
  
            in.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
} 











你可能感兴趣的:(Head First 设计模式--装饰者模式)