有时候我们需要拓展一个类的功能或者给类添加附加职责,一种方式是创建继承自该类的新类,另外一种方法是创建新类,然后将该类的对象作为参数传入,后面这种方法就是装饰模式。装饰模式就是创建一个包装对象,来装饰包裹的真实的对象。
装饰对象和真实对象有相同的接口。这样客户端对象就能以和真相对象相同的方式和装饰对象交互。
装饰对象包含一个真实对象的引用。
装饰对象接收所有来自客户端的请求,它把这些请求转发给真实的对象。
装饰对象可以在转发这些请求以前或者以后增加一些新功能。
装饰模式比继承更加灵活机动,同时也意味着更多的复杂性,装饰模式会导致设计中出现许多小类,过度使用会使得程序变得复杂。
我们打个比方来解释一下这个装饰模式:
面粉公司要进军手机业,然后公司想要出多款机型去占领不同的市场:
针对年轻人的高音质手机
针对商务人士的长待机手机
年度旗舰机,又高音质,又长待机
有一种解决方案是去富士康租三条生产线嘛,每条生产线生产一种手机,当然,这种方法也可以,但是如果又出来多种机型呢?总不能每个机型都去租一条生产线吧,多费钱!另外一种解决方法是只租一条生产线,生产基础功能的手机,然后在需要生产音乐手机的时候把高音喇叭装上去,需要生产待机手机时候,就把大容量电池装上去...
基础手机模型
public interface Phone {
public void call();//手机基础功能---打电话
}
基础手机实例
public class BasicPhone implements Phone {
@Override
public void basicAbility() {
System.out.println("通话...");
}
}
这里就需要针对各种机型来做出相应的包装了,提供一个“包装模板”
public abstract class PhoneDecorate implements Phone {
private Phone phone;
public PhoneDecorate(Phone phone){
this.phone = phone;
}
@Override
public void basicAbility() {
this.phone.basicAbility();
}
}
针对音乐手机做包装
public class MusicPhoneDecorate extends PhoneDecorate{
public MusicPhoneDecorate(Phone phone) {
super(phone);
}
@Override
public void basicAbility() {
// TODO Auto-generated method stub
super.basicAbility();
playMusic();
}
private void playMusic(){
System.out.println("播放音乐..");
}
}
针对商务手机做包装
public class BigBatteryPhoneDecorate extends PhoneDecorate {
public BigBatteryPhoneDecorate(Phone phone) {
super(phone);
}
@Override
public void basicAbility() {
super.basicAbility();
BigBattery();
}
private void BigBattery() {
System.out.println("超大电池容量");
}
}
现在就可以上生产线了
public class PhoneDemo {
public static void main(String[] args) {
//生产基础手机
Phone basicPhone = new BasicPhone();
basicPhone.basicAbility();
System.out.println("======================");
//生产音乐手机
PhoneDecorate musucPhone = new MusicPhoneDecorate(basicPhone);
musucPhone.basicAbility();
System.out.println("======================");
//生产商务手机
PhoneDecorate batteryPhone = new BigBatteryPhoneDecorate(basicPhone);
batteryPhone.basicAbility();
System.out.println("======================");
//生产旗舰手机
PhoneDecorate proPhone = new BigBatteryPhoneDecorate(new MusicPhoneDecorate(basicPhone));
proPhone.basicAbility();
}
}
输出结果:
通话...
======================
通话...
播放音乐..
======================
通话...
超大电池容量
======================
通话...
播放音乐..
超大电池容量
解释一下装饰模式
//生产音乐手机
PhoneDecorate musucPhone = new MusicPhoneDecorate(basicPhone);
musucPhone.basicAbility();
首先MusicPhoneDecorate对象的参数是一个BasicPhone对象,而这个对象实现了Phone接口。
紧接着MusicPhoneDecorate对象调用了其basicAbility()方法,实际上是调用了其父类的basicAbility()方法,因为
super.basicAbility();
去看其父类
public abstract class PhoneDecorate implements Phone {
private Phone phone;
public PhoneDecorate(Phone phone){
this.phone = phone;
}
@Override
public void basicAbility() {
this.phone.basicAbility();
}
}
其父类调用的正式传入的参数的BasicPhone对象的basicAbility方法,也就是说,手机的"通话..."功能是BasicPhone对象提供的。
紧接着MusicPhoneDecorate对象在basicAbility方法内部又调用了playMusic方法,也就是说这个播放音乐的功能是另外添加的,就相当于一个“装饰物”。
是不是清楚一些了??
之前的装饰模式中说过,装饰模式中有一个抽象装饰类,来帮助我们衍生各种不同功能的具体装饰类,Java IO 体系中也有这样的抽象装饰类:
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
去看一下他们的源码就会发现,他们只是传入一个抽象类,由他们的子类(具体装饰类)去添加一些具体的功能。
FilterInputStream常用的子类有:
BufferedInputStream
DataInputStream
FilterOutputStream常用的子类有:
BufferedOutputStream
DataOutputStream
FilterReader常用的子类有:
FilterWriter常用的子类有:
http://www.jianshu.com/p/eda2a396f572
http://www.jianshu.com/p/24d88fb3fe18