装饰者模式
一、简介
装饰模式使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种代替方案。
定义:动态地给一个对象添加一些额外的职责,就增加功能来说装饰模式相比生成子类更加灵活。
二、使用场景
需要透明且动态的扩展类的功能时。
三、简单实现
这里以房间装饰为例简单的实现装饰模式,我们知道一间屋子最什么都不装饰会显得空荡无趣,所以大家总会用一些家具、壁纸等装饰房间。
//抽象房屋类
public abstract class Room{
public abstract void decorator();
}
public class EmptyRoom extends Room{
@Override
public void decorator() {
Log.i(TAG, "simple decorator room ");
}
}
//抽象装饰类
public abstract class DecoratorRoom extends Room{
private Room room;
public DecoratorRoom(Room room) {
this.room = room;
}
@Override
public void decorator() {
room.decorator();
}
}
//具体装饰类
public class BedRoom extends DecoratorRoom{
public BedRoom(Room room) {
super(room);
}
@Override
public void decorator() {
super.decorator();
bed();
}
private void bed(){
Log.i(TAG, "put a bed:");
}
}
public class LivingRoom extends DecoratorRoom{
public LivingRoom(Room room) {
super(room);
}
@Override
public void decorator() {
super.decorator();
sofa();
}
private void sofa(){
Log.i(TAG, "put a sofa: ");
}
}
public void test(){
EmptyRoom emptyRoom=new EmptyRoom();
BedRoom bedRoom=new BedRoom(emptyRoom);
bedRoom.decorator();
LivingRoom livingRoom=new LivingRoom(emptyRoom);
livingRoom.decorator();
}
四、小结
在Android中使用装饰者模式的例子就是Context,我们知道activity、application等都继承了Context,实际上他们就是Context的装饰类。Context是一个抽象类自定义了相关操作并未实现,真正的实现类是ContextImpl,所以这里的Context相当于上面例子的Room而ContextImpl相当于EmptyRoom。再来说Activity,它继承自ContextThemeWrapper,ContextThemeWrapper又继承自ContextWrapper,ContextWrapper继承自Context,这里的ContextWrapper就相当于装饰者抽象类,其子类Activity相当于具体的装饰类。
通过学习我们发现装饰者模式和代理模式有点类似,但是它们是有区别的:
- 代理模式只对代理的对象施加控制并不会对对象本身的功能进行增强
- 装饰模式是以对客户端透明的方式扩展对象功能已达到对对象的增强,它也是继承关系的一个替代方案