1.职责:
<1>动态为一个新的对象增加新的功能
<2>装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的功能。使用对象的关联关系代替继承关系,更加灵活,避免了类型体系的快速膨胀。
2.角色:
<1>Component抽象构件角色
真实对象和装饰对象拥有相同的接口。这样客户端对象就能够以与真实对象相同的方式和装饰对象进行交互
<2>ConcreteComponent具体构件角色(真实对象)
io流中的FileInputStream,FileOutputStream
<3>Decrator装饰对象
持有抽象构个的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实对象。这样就能在对象调用前后增加新功能
3.开发使用场景
<1>IO中输入流和输出流的设计
<2>Swing包中图形界面构件功能
<3>Servlet API中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类增强了request对象的功能
<4>Struts2中,request,response,session对象的处理
附IO流实现细节:
<1>Component抽象构件角色:io流中的InputStream,OutputStream,Reader,Writer
<2>ConcreteComponent具体构件角色:io流中的FileInputStream,FileOutputStream
<3>Decorator装饰角色:持用抽象构件的引用:io流中FilterInputStream,FilterOutputStream
<4>ConcreteDecorator具体装饰角色:负责给抽象构件增加新的责任:io流中的BufferedInputStream,BufferedOutputStream
4.装饰模式和桥接模式区别:
两个模式都是为了解决过多子类对象的问题,但他们的诱因不一样
桥接模式是对象自身现有机制沿着多个维度变化,是有部分不稳定
装饰模式是为了增加新的功能
5.装饰模式优缺点:
优点:
<1>扩展对象功能,比继承灵活,不会导致类的个数急剧增加
<2>可以对一个对象进行多次装饰,创造出不同的行为组合,得到功能更强大的对象
<3>具体构件和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类
缺点:
<1>产生很多小对象。大量小对象占据内存,一定程序影响性能
<2>装饰模式易于出错,调试比较麻烦
6.示例代码
<1>各个组件
//抽象构件角色
public interface ICar {
void move();
}
//具体构件角色
class Car implements ICar{
@Override
public void move() {
System.out.println("car is move");
}
}
//装饰角色
class DecoratorCar implements ICar{
protected ICar car;
public DecoratorCar(ICar car) {
super();
this.car = car;
}
@Override
public void move() {
car.move();
}
}
//具体装饰角色
class FlyDecoratorCar extends DecoratorCar{
public FlyDecoratorCar(ICar car) {
super(car);
}
public void fly(){
System.out.println("car can fly");
}
@Override
public void move() {
super.move();
fly();
}
}
//具体装饰角色
class WaterDecoratorCar extends DecoratorCar{
public WaterDecoratorCar(ICar car) {
super(car);
}
public void swim(){
System.out.println("car can swim");
}
@Override
public void move() {
super.move();
swim();
}
}
//具体装饰角色
class AIDecoratorCar extends DecoratorCar{
public AIDecoratorCar(ICar car) {
super(car);
}
public void automove(){
System.out.println("car can automove");
}
@Override
public void move() {
super.move();
automove();
}
}
<2>客户端
public class Client {
public static void main(String[] args) {
//普通car
ICar car=new Car();
car.move();
//可以飞行的car
ICar flyCar=new FlyDecoratorCar(car);
flyCar.move();
//可以水陆两栖car
ICar waterCar=new WaterDecoratorCar(car);
waterCar.move();
//水陆空自动驾驶car
ICar aiFlyWaterCar=new AIDecoratorCar(new WaterDecoratorCar(new FlyDecoratorCar(new Car())));
aiFlyWaterCar.move();
}
}
<3>执行结果:
car is move
car is move
car can fly
car is move
car can swim
car is move
car can fly
car can swim
car can automove