Java设计模式之装饰模式
装饰模式指的是在不必改变原类文件和不使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
组成
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象
- 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口
- 具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任
设计原则
- 多用组合,少用继承
- 类应遵守开闭原则
装饰模式的优点
装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰可以提供比继承更多的灵活性。
即装饰模式允许动态添加或删除所装饰的内容,继承关系则不同,继承关系是静态的,它在系统运行前就决定了。通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
装饰模式的缺点
这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。
当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。
应用举例
第一步:定义抽象构件(Component)角色
/**
* Created by yunzhao.liu on 2017/12/28
* 抽象构件(Component)角色
*/
public interface IHouse {
/**
* 住、生活
*/
void live();
}
第二步:定义具体构件(Concrete Component)角色
/**
* Created by yunzhao.liu on 2017/12/28
* 具体构件(ConcreteComponent)角色
*/
public class MyHouse implements IHouse {
@Override
public void live() {
System.out.println("我住在我的房子里");
}
}
第三步:定义装饰(Decorator)角色
/**
* Created by yunzhao.liu on 2017/12/28
* 装饰(Decorator)角色
*/
public class Decorator implements IHouse{
private IHouse mHouse;
public Decorator(IHouse house) {
this.mHouse = house;
}
@Override
public void live() {
mHouse.live();
}
}
第四步:定义具体装饰(Concrete Decorator)角色
/**
* Created by yunzhao.liu on 2017/12/28
* 具体装饰角色-注重安全
*/
public class SecurityDecorator extends Decorator{
public SecurityDecorator(IHouse house) {
super(house);
}
@Override
public void live() {
super.live();
System.out.println("我住的房子很安全");
}
}
/**
* Created by yunzhao.liu on 2017/12/28
* 具体装饰角色-注重漂亮
*/
public class BeautifulDecorator extends Decorator {
public BeautifulDecorator(IHouse house) {
super(house);
}
@Override
public void live() {
super.live();
System.out.println("我住的房子很漂亮");
}
}
第五步:测试
/**
* Created by yunzhao.liu on 2017/12/28
* 测试类
*/
public class TestD {
public static void main(String[] args) {
//只注重外表
IHouse beautifulHouse = new MyHouse();
IHouse beautiful = new BeautifulDecorator(beautifulHouse);
beautiful.live();
System.out.println("---------------------");
//只注重安全
IHouse securityHouse = new MyHouse();
IHouse security = new SecurityDecorator(securityHouse);
security.live();
System.out.println("---------------------");
//都注重
IHouse house = new MyHouse();
IHouse beautiful1 = new BeautifulDecorator(house);
IHouse security1 = new SecurityDecorator(beautiful1);
security1.live();
}
}
打印结果
我住在我的房子里
我住的房子很漂亮
---------------------
我住在我的房子里
我住的房子很安全
---------------------
我住在我的房子里
我住的房子很漂亮
我住的房子很安全