装饰者模式
原文链接:什么是装饰者模式
文章目录
前言
动态的给一个对象添加额外的功能,装饰者模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
要点: 装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为
一、如何构建?
1、Component(抽象构件角色)
真实对象和装饰对象有相同的接口,这样,客户端对象就能够以与真实对象相同的方式同装饰对象进行交互。
2、ConcreteComponent(具体构件角色,即真实对象)
IO流中的FileInputStream、FileOutputStream
3、Decorator(装饰角色)
持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
4、ConcreteDecorator(具体装饰角色)装饰者
负责给构件对象增加新的责任。
二、构建一个装饰器模式实列
需求:有一群普通小鸟,每次飞行只能飞100米,想要不改变其它小鸟的飞行距离,又想让其中一只小鸟变成超级小鸟飞行150米。这里就需要给这只超级小鸟加上一个装饰器,祝它一飞冲天!!!
1.设置一个抽象组件
这里的抽象组件是小鸟:创建抽象组件
提供一个小鸟飞行的方法,可以返回小鸟的飞行距离
public abstract class Bird {//抽象组件
//提供一个 鸟儿飞行距离的方法
public abstract int fly();
}
2.创建具体抽象组件
也就是创建 抽象组件小鸟的具体实现
具体实现了小鸟的飞行距离
public class BirdFly extends Bird{ //具体组件
private static final int DISTANCE=100; //鸟儿发飞行距离只能是100
@Override
public int fly() {
return DISTANCE;
}
}
3.创建抽象的装饰器角色
这个角色继承了 抽象小鸟组件,并且提供一个 被装饰者(也就是小鸟)类型的变量,用来 保存被装饰者的引用
public abstract class Decorator extends Bird{ //装饰器
//与具体组件(需要被装饰的组件) 继承了相同的抽象组件
//但是多了一个 含有抽象组件声明的变量,用于保存 被装饰者 的实列
protected Bird bird;
public Decorator(){
}
public Decorator(Bird bird){
this.bird=bird;
}
}
4.创建装饰器角色的具体实现
通过引用被装饰对象方法的方式来实现 被装饰者(小鸟)的 fly方法,并且调用自己私有的装饰方法,为这个方法提供了增强。
public class DecoratorFly extends Decorator{//装饰者(具体的装饰)
private static final int DISTANCE=50;
public DecoratorFly(Bird bird){
super(bird); //调用父类的构造方法,保存需要被装饰的小鸟的引用
}
@Override
public int fly() {
return bird.fly()+superFly();//委托被装饰者 BirdFly 调用 fly()方法,然后再调用 superFly()
}
//装饰者提供的方法,私有化,只能由装饰着来支配它
private int superFly(){
return DISTANCE;
}
}
5.实现
public class Main {
public static void main(String[] args) {
//普通小鸟飞行
BirdFly birdFly1 = new BirdFly();
int fly = birdFly1.fly();
System.out.println("普通小鸟飞行了"+fly+"米");
//加了装饰器的小鸟 飞行
BirdFly birdFly2 = new BirdFly();//获取一直普通小鸟
DecoratorFly superBird = new DecoratorFly(birdFly2);//给小鸟加上装饰 成为超级小鸟
int superFly = superBird.fly();
System.out.println("超级小鸟飞行了"+superFly+"米");
}
}
6. 如果想要小鸟飞 200 米喃?
//那就给小鸟加上两个装饰器
BirdFly birdFly3 = new BirdFly();
//加第一个装饰 成为超级小鸟
DecoratorFly superBird1 = new DecoratorFly(birdFly3);
//再给小鸟加一个装饰器 成为超超级小鸟
DecoratorFly superBirdPlus = new DecoratorFly(superBird1);
System.out.println("超超级小鸟飞了"+superBirdPlus.fly()+"米");
总结
抽象组件:定义一个抽象接口,来规范准备附加功能的类。
具体组件:将要被附加功能的类,实现抽象构件角色接口。
抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口。
具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。
装饰者当中的装饰方法,应该设置为私有的,也就是只能由装饰者来支配它。