java设计模式 ——装饰者模式

什么是装饰者模式

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。


                                    图来自百度百科


例子

//饮料
public abstract class Beverage {
	//描述
	String description = "Unknown Beverage";
	
	public String getDescription() {
		return description;
	}
	//计算价格
	public abstract double cost();
}
//无咖啡因咖啡
public class Decaf extends Beverage {
	
	public Decaf() {
		description = "Decaf";
	}
	public double cost() {
		return 1.64;
	}

}
//浓咖啡
public class Espresso extends Beverage {
	public Espresso() {
		description = "Espresso";
	}
	public double cost() {
		return 1.99;
	}
}
装饰者
//调料的装饰者类
public abstract class CondimentDecorator extends Beverage {
	//重写getDescription()方法
	public abstract String getDescription();
}
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 .30 + beverage.cost();
	}

}

测试类

public class Test {
	public static void main(String[] args) {
		System.out.println("====================price====================");
		System.out.println("Decaf:1.64  Espresso:1.99  Mocha:0.2 Soy:0.3");
		System.out.println("====================price====================");
		
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription() + " $" +
				beverage.cost());
		
		Beverage beverage2 = new Decaf();
		beverage2 = new Mocha(beverage2);
		beverage2 = new Mocha(beverage2);
		beverage2 = new Soy(beverage2);
		System.out.println(beverage2.getDescription() + " $" +
				beverage2.cost());
	}
}

输出

====================price====================
Decaf:1.64  Espresso:1.99  Mocha:0.2 Soy:0.3
====================price====================
Espresso $1.99

Decaf,Mocha,Mocha,Soy $2.34


装饰者模式在java.io类中的使用

                                                图来自java io流类图


从上图可发现,java.io类设计时利用了装饰者模式,也引出了装饰者模式的一个“缺点”:利用装饰者模式,常常造成设计中有大量的小类,数量过多,可能会造成使用此API程序员的困扰。

编写自己的Java I/O装饰者

编写一个装饰者,把输入流内的所有大写字符转成小写。

装饰者类

//拓展FilterInputStream的装饰者类,实现将大写字符转为小写字符
public class LowerCaseInputStream extends FilterInputStream {

	protected 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;
	    }
}
测试类
public class Test {
	public static void main(String[] args) throws IOException {
		int c;
		try {
			InputStream in = new LowerCaseInputStream(
					new BufferedInputStream(
							new FileInputStream("D:/test.txt")));
			while((c = in.read()) >= 0) {
				System.out.print((char)c);
			}
			in.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}

读入文件

HELLO WORLD

Hello Zy

输出内容

hello world

hello zy


参考:

《Head First 设计模式》

猜你喜欢

转载自blog.csdn.net/qq_34902684/article/details/79463001