java装饰者模式

装饰者模式:给一个对象增加一些新的功能,而且要求是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

假如我们想对房子进行装饰,首先得有一个House接口,里面有装饰的方法,代表是装饰房子这样的一个通用的特性。

House接口:

public interface House {
	//刷墙漆
	public void paint();
	//贴墙纸
	public void wallpaper();
}
然后定义一个抽象的装饰类Decorator实现House接口,Decorator类:

public abstract class Decorator implements House {
	//持有被装饰对象引用
	private House house;
	public Decorator(House house){
		this.house = house;
	}
	
	@Override
	public void paint() {
		house.paint();
	}

	@Override
	public void wallpaper() {
		house.wallpaper();
	}
}
接下来就会有三个人分别来装饰房子,他们都要继承抽象的装饰类Decorator。

PersonOne类:

public class PersonOne extends Decorator {
	public PersonOne(House house) {
		super(house);
	}

	@Override
	public void paint() {
		super.paint();
		System.out.println("选购墙漆");
	}
	@Override
	public void wallpaper() {
		super.wallpaper();
		System.out.println("选购墙纸");
	}
}

PersonTwo类:

public class PersonTwo extends Decorator {
	public PersonTwo(House house) {
		super(house);
	}

	@Override
	public void paint() {
		super.paint();
		System.out.println("墙漆的用量勾兑,搅匀");
	}

	@Override
	public void wallpaper() {
		super.wallpaper();
		System.out.println("剪裁墙纸");
	}
}

PersonThree类:

public class PersonThree extends Decorator{
	public PersonThree(House house) {
		super(house);
	}

	@Override
	public void paint() {
		super.paint();
		System.out.println("开始刷墙漆");
	}

	@Override
	public void wallpaper() {
		super.wallpaper();
		System.out.println("开始贴墙纸");
	}
}

三个人要做的工作都已经安排好了,现在我们要选择一个房间来装饰,就选卧室吧

BedRoom类:

public class BedRoom implements House {
	@Override
	public void paint() {
		System.out.println("我要装饰卧室,打算刷点墙漆");
	}

	@Override
	public void wallpaper() {
		System.out.println("---------感觉还不太满意");
		System.out.println("我还打算贴点墙纸");
	}
}


房间也选好了,开始动工吧。

DecoratorTest类:

public class DecoratorTest {
	public static void main(String[] args) {
		House house = new BedRoom();
		Decorator decorator = new PersonThree(new PersonTwo(new PersonOne(house)));
		decorator.paint();
        decorator.wallpaper();
	}
}

输出结果:我要装饰卧室,打算刷点墙漆
                    选购墙漆
                     墙漆的用量勾兑,搅匀
                     开始刷墙漆
                     ---------感觉还不太满意
                    我还打算贴点墙纸
                    选购墙纸
                    剪裁墙纸
                    开始贴墙纸

这样房间就算装饰完了,大功告成。

其实装饰者模式在java中运用很广泛的,比如IO流中,运用了大量的装饰者模式。以InputStream为例,从装饰者模式来看下InputStream的结构。

InputStream的类图关系 
class java.lang.Object 

|—class java.io.InputStream //输入流,字节形式,为以下的基类 
| | 
| |——java.io.ByteArrayInputStream //从字节数组中读取 
| | 
| |——java.io.FileInputStream //从文件中读取数据 
| | 
| |—— java.io.FileInputStream //过滤流的基类, 
| | | // 过滤可以了解为各种处理技术的形象称呼 
| | | 
| | |——java.io.BufferedInputStream //缓冲技术,数据来自底层输入流 
| | | 

| | |——java.util.zip.CheckedInputStream //用于维护数据校验和

| | |

| | |——javax.crypto.CipherInputStream //属于Cipher类的扩展,称为密钥流

| | | 
| | |——java.io.DataInputStream //可读java数据类型 
| | | 

| | |——java.util.zip.DeflaterInputStream //压缩数据的输入流 
| | | 

| | |——java.security.DigestInputStream //消息摘要输入流,可以通过读取输入流的方式完成摘要更新 
| | | 

| | |——java.util.zip.InflaterInputStream //解压缩 "deflate" 压缩格式的数据实现流过滤器。它还用作其他解压缩过滤器(如 GZIPInputStream)的基础。

| | | 

| | |——java.io.LineNumberInputStream //输入流过滤器,提供当前行号的附加功能(已过时)

| | | 

| | |——javax.swing.ProgressMonitorInputStream  //监视读取某些 InputStream 的进度 
| | |

| | |——java.io.PushbackInputStream //允许我们试探性的读取数据流,如果不是我们想要的则返还回去,之所以能够这样,因为其内部维护了一个pushback buffer缓冲区。 

| | | 
| | |——java.util.zip.GZIPInputStream //继承InflaterInputStream,读取 GZIP 文件格式的压缩数据实现流过滤器
| | | 
| |—— ....... 

从以上可以看出,InputStream就是装饰者模式中的超类(Component),ByteArrayInputStream、FileInputStream相当于被装饰者(ConcreteComponent),这些类都提供了最基本的字节读取功能。而另外一个和这两个类是同一级的FilterInputStream即是装饰者(Decorator),BufferedInputStream、DataInputStream、PushbackInputStream......这些都是被装饰者装饰后形成的成品。

根据装饰者模式的特点,我们可以总结出这些IO流的使用方法:

File file = new File ("test.txt"); 
FileInputStream in=new FileInputStream(file); 
BufferedInputStream inBuffered=new BufferedInputStream (in); 
这里的BufferedInputStream主要是提供了缓存机制,先读入一个byte[],等count到达缓存Byte[]的大小的时候,再一次读入。你也可以写成:

BufferedInputStream inBuffered = new BufferedInputStream (new FileInputStream(new File ("test.txt")));
从使用者的角度来看装饰者模式,可以看出它的一个缺点:装饰者模式的实现对于使用者是透明的。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值