您的位置:首页 > 其它

设计模式的应用场景(9)--装饰模式

2017-08-29 14:08 471 查看

装饰模式

定义:装饰模式以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案,提供比继承更多的灵活性。

优点:能够提供比使用继承关系更加灵活的拓展对象的功能,它可以动态增加对象的功能并且可以随意组合这些功能。

缺点:使用装饰模式进行设计往往会产生很多看上去相似的小对象。

使用时机:当系统需要扩展一个类的功能,或者客户端需要动态的给一个对象添加功能,并且使用继承会很复杂时候。

其实对于装饰者模式大家并不陌生,相反接触的还很平凡,因为Java中的IO机制就用到了装饰者模式。比如大家最常用的语句:

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filepath)));

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));


就是最常见的装饰者模式了,通过BufferedReader对已有对象FileReader的功能进行加强和优化。其实它不仅可以加强FileReader,所有的字符输入流都可以通过这种方式进行包装。它是如何实现的呢?注意重点来了:其实很简单,它只不过将所有的字符输入流抽象出了一个基类或接口 即Reader,然后通过构造方法的形式将Reader传递给BufferedReader,此时BufferedReader就可以对所有的字符输入流进行拦截和优化了。

  试想一下,如果采用继承机制,每个XXXReader就要衍生出一个BufferedXXXReader,再加上字符输出流和字节输入输出流,那么Java的IO体系结构该是多么的臃肿不堪啊!而装饰者模式的出现解决了这个问题,并且,装饰者的出现也再一次的证明了面向对象的设计原则:多用组合,少用继承!对扩展开放,对修改关闭!

下面再给出一个例子,

小巩需要为公司设计手机相关的业务,

public interface Phone {
void call(String name);
}
public class PhoneImpl implements Phone {
public void call(String name) {
System.out.println(name + " 正在通话中");
}
}


彩铃手机

public class ColorPhoneDecorator extends PhoneDecorator {
public ColorPhoneDecorator(Phone phone) {
super(phone);
}

public void call(String name) {
System.out.println("播放彩铃");
super.call(name);
}
}


广告手机

public class AdPhoneDecorator extends PhoneDecorator {
public AdPhoneDecorator(Phone phone) {
super(phone);
}

public void call(String name) {
super.call(name);
System.out.println("播放广告");
}
}


假如客户需要支持彩铃和广告的手机

public class Client {
public static void main(String[] argv) {
Phone phone = new PhoneImpl();
//如果需要彩铃的手机
PhoneDecorator phoneDecorator = new ColorPhoneDecorator(phone);
//  phoneDecorator.call("张三");
//如果需要广告的手机
//phoneDecorator = new AdPhoneDecorator(phone);
//phoneDecorator.call("张三");
//如果需要既播放彩铃又播放广告的手机
phoneDecorator = new AdPhoneDecorator(phoneDecorator);
phoneDecorator.call("张三");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: