Java设计模式之装饰模式
2016-03-10 14:44
435 查看
装饰器模式
在不改变原有类和继承关系的基础上,动态地拓展一个对象的功能。通过创建一个包装对象,包裹真实的对象,以完成功能的拓展。想象一个场景,你有一辆车,它可以在陆地上跑,现在我需要一辆能在水里开的车。怎么办?继承汽车类,然后新增方法runInWater()?
好,可以。那么我现在需要一辆能飞的车。怎么办?继承汽车类,然后新增方法runInAir()?
好,可以。那么我现在需要一辆即能在水里开,又能在空中飞的车。怎么办?Java不支持多继承,难道又要去继承汽车类?还是去继承能在水里开的车,抑或是能飞的车?
然后功能继续增加,你就疯了。
在桥接模式的时候,已经疯过一次了,这里不能再疯了。
装饰模式和桥接模式的区别:
两个模式都是为了解决过多子类对象的问题,但是他们的诱因不同。桥接模式是对象自身现有机制沿多个维度变化,是既有部分不稳定,装饰模式是为了增加新的功能。
下面开始上代码。本文示例,就是上述的多功能汽车。(本文示例参考自北京尚学堂Java教程,高淇)
先来一个汽车接口,只有一个方法move():
public interface ICar {
void move();
}再来一个ConcreteComponent具体构建对象,这就是真实对象:
//ConcreteComponent具体构件对象(真实对象)
class Car implements ICar{
@Override
public void move() {
System.out.println("陆地上跑!");
}
}之后就是Decorator装饰对象:
//Decorator装饰角色 class SuperCar implements ICar{ protected ICar car; public SuperCar(ICar car) { super(); this.car = car; } @Override public void move() { car.move(); } }装饰对象实现了ICar接口,并且持有一个ICar的引用,在重写的move()函数中,实际调用的传入的ICar引用的move()方法。
接着是具体的装饰角色:
//ConcreteDecorator具体装饰角色
class FlyCar extends SuperCar{
public FlyCar(ICar car) {
super(car);
}
public void fly(){
System.out.println("天上飞");
}
@Override
public void move() {
super.move();
fly();
}
}
class WaterCar extends SuperCar{ public WaterCar(ICar car) { super(car); } public void swim(){ System.out.println("水里游"); } @Override public void move() { super.move(); swim(); } }
class AICar extends SuperCar{ public AICar(ICar car) { super(car); } public void autoMove(){ System.out.println("自动驾驶"); } @Override public void move() { super.move(); autoMove(); } }最后测试一下:
public class Client {
public static void main(String[] args) {
Car car = new Car();
car.move();
System.out.println("==增加飞行功能==");
FlyCar flyCar = new FlyCar(car);
flyCar.move();
System.out.println("==增加水上功能==");
WaterCar waterCar = new WaterCar(car);
waterCar.move();
System.out.println("==全能车==");
AICar aiCar = new AICar(new FlyCar(new WaterCar(car)));
aiCar.move();
}
}首先我们有一个具体的真实对象Car,普通的车。开起来car.move();接着我们给他增加一个飞行功能,外面装饰一层FlyCar,开起来flyCar.move();再来一个全能车,装饰100层
看下输出:
陆地上跑!
==增加飞行功能==
陆地上跑!
天上飞
==增加水上功能==
陆地上跑!
水里游
==全能车==
陆地上跑!
水里游
天上飞
自动驾驶
可以看到,随着装饰的层数增加,功能也增多了,但是没有增加多余的类。
总结:
装饰模式(Decorator)也叫包装器模式(Wrapper)装饰模式降低系统耦合度,可以动态地增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。
优点:
-拓展对象功能,比继承灵活,不会导致类个数急剧增加
-可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
-具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构建子类和具体装饰子类
确定:
-产生很多小对象。大量小对象占据内存,一定程度上影响性能。
-装饰模式易于出错,调试排查比较麻烦。
常用场景:
IO流实现细节就是典型的装饰模式-Component抽象构件角色:
·io流中的InputStream、OutputStream、Reader、Writer
-ConcreteComponent具体构建角色
·io流中的FileInputStream、FileOutputStream
-Decorator装饰角色:
·持有一个抽象构件的引用:io流中的FilterInputStream、FilterOutputStream
-ConcreteDecorator具体装饰角色:
·负责给构建对象增加新的责任。io流中的BufferedOutputStream、BufferedInputStream等。
相关文章推荐
- Java设计模式之装饰模式(Decorator模式)介绍
- C++设计模式之装饰模式
- 学习php设计模式 php实现装饰器模式(decorator)
- java设计模式之装饰模式详细介绍
- 从赵本山的小品联想到的Java设计模式
- JAVA设计模式学习第三天 设计模式之Chain of Responsibility——项目篇
- 学习:java设计模式—工厂模式
- 装饰模式
- 设计模式----简单工厂模式
- 装饰模式
- 装饰模式-设计模式(三)
- Decorator模式
- Java设计模式 创建模式-工厂模式(Factory)
- Java设计模式 创建模式-原型模式(Prototype)
- Java设计模式 创建模式-生成器模式(Builder)
- Java设计模式 创建模式-单态模式(Singleton)
- Java设计模式 结构模式-适配器模式(Adapter)
- 《Java设计模式》七大原则
- C++ 装饰模式
- 设计模式-创建型:单例模式(1)