装饰模式
职责:
动态的为一个对象添加新的功能
装饰模式i是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能,使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀
现在假设:有一辆汽车 ,我们需要他实现 会飞,会游泳,会自动驾驶的功能,我们没有用设计模式之前应该是 定义一个接口,定义3个子类去实现. 那么我现在有需要他既会飞又会游泳呢?是不是还需要继续实现和extends
如果现在要求3种都会呢?那么我们是不是需要继续extends
现在我们用装饰模式来实现下这的功能
类图如下:
代码:
/** * compent 组件 具有真实对象和 装饰对象相同的接口,这样 * 客户端可以和真实的对象一样和装饰对象交互 */ public interface CarComponent { void move(); } /** * 真实的类 */ public class Car implements CarComponent { @Override public void move() { System.out.println("真实的汽车"); } } /** * 装饰的类 */ public class DecoratorCar implements CarComponent{ protected CarComponent carComponent; public DecoratorCar(CarComponent carComponent) { this.carComponent = carComponent; } @Override public void move() { carComponent.move(); } } public class FlyCar extends DecoratorCar { public FlyCar(CarComponent carComponent) { super(carComponent); } public void fly(){ System.out.println("汽车飞起来了"); } @Override public void move() { super.move(); fly(); } } public class WaterCar extends DecoratorCar { public WaterCar(CarComponent carComponent) { super(carComponent); } public void swim(){ System.out.println("i'm siwmming "); } @Override public void move() { super.move(); swim(); } } public class AICar extends DecoratorCar { public AICar(CarComponent carComponent) { super(carComponent); } public void ai(){ System.out.println("auto move car"); } @Override public void move() { super.move(); ai(); } } public class Clinet { public static void main(String[] args) { CarComponent car = new Car(); car.move(); DecoratorCar car1 = new DecoratorCar(new FlyCar(car)); car1.move(); System.out.println("水车和ai组合==============="); DecoratorCar car2 = new WaterCar(new AICar(car)); car2.move(); } }
现在我们有3个子类,分别会飞 会游泳 会自动驾驶,,现在我们把他们组合一下,让一个简单得汽车用这几个功能
public class Clinet { public static void main(String[] args) { CarComponent car = new Car(); System.out.println("fly swim ai auto--------------------------"); DecoratorCar car2 = new WaterCar(new AICar(new FlyCar(car))); car2.move(); } }
就这么简单就可以了.如果不适用这样的模式的话,我们有俩种办法 1. 新建一个类 他继承 会飞 会游泳的,会自动驾驶的,或者实现一个接口 把这3个都写进行,但是这样的话不够灵活,不易扩展
实现细节
component: 抽象构建角色
真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互
ConcreteComponent 具体构件角色(真实对象) :
真实的对象
Decorator装饰角色
他持有了一个构建角色的引用,装饰对象接受对客户端的请求,并发这样请求转发给真实的对象,这样就可以在真实的对象前后实现自己的逻辑
concreteDecorator角色
负责给对象添加新的功能
总结
装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新
的具体构建类和具体装饰类
优点:
1. 扩展对象比继承灵活,不会导致类个数急剧增加
2. 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
3. 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类
缺点:
产生很多小对象,大量的小对象占据内存,一定程度上影响性能
装饰模式出错的话,调试排查比较麻烦
对比:
装饰模式和桥接模式的区别
两个模式都是为了解决过多子类对象问题。但他们的诱因不一样。桥 模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能
和代理模式对比
代理模式是在一个方法上添加将相同的操作提取出去,装饰模式是,增加新的功能
jdk中用到的地方:
IO流我随意找了一个地方就.大家可以看看类图