概念:
通过使用修饰模式,可以在运行时扩充一个类的功能。
原理:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
注意:
修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
模式中的角色
抽象构建(Component):定义一个抽象接口,用以给这些对象动态地添加职责。
具体构建(ConcreteComponent):定义一个具体的对象,也可以给这个对象添加一些职责。
装饰类(Decorator): 装饰抽象类,继承了Component,从外类来扩展Component类的功能。
具体装饰者(ConcretorDecorator):负责给构建对象添加职责。
装饰模式的一般化类图
核心代码
/**
* Created by zhangjiqiang on 2017/1/4.
*/
public abstract class FruitDecorator implements Basket {
private Basket basket;
public FruitDecorator(Basket basket){
this.basket=basket;
}
public void show(){
basket.show();
}
}
class AppleDecorator extends FruitDecorator{
public AppleDecorator(Basket basket){
super(basket);
}
@Override
public void show() {
super.show();
System.out.println("add an apple");
}
}
装饰器模式就像包装纸,给对象加上一层又一层组合的包装后对象就相当于定制化了功能,比如一个礼盒加上防水和夜光的包装纸后,礼盒就具有了防水和夜光的功能。
适用场景
- 当需要为已有功能动态地添加更多功能时。
- 类的核心功能无需改变,只是需要添加新的功能时。
实际场景
假设我们有一个水果篮子,厘米可以装苹果,香蕉、或者橘子。这是可以典型的应用装饰器模式,比如我们用三个修饰器来修饰水果篮子里面装的内容。假设我们使用继承的话,那么要想获得所有情况,根据排列组合那么就有8种可能,需要有7个子类(空篮子就是本身,不需继承了)。装饰器模式就简单多了
demo示例
定义一个篮子接口, 对应角色中的-->Component
/**
* Created by zhangjiqiang on 2017/1/4.
*/
public interface Basket {
public void show();
}
定义篮子的基础实现类,对应角色中的 -->ConcreteComponent
/**
* Created by zhangjiqiang on 2017/1/4.
*/
public class NormalBasKet implements Basket {
@Override
public void show() {
System.out.println("This is a normal basket.");
}
}
定义装饰抽象类作为模具,此模具可定制各种功能组合,对应角色中的-->Decorator
/**
* Created by zhangjiqiang on 2017/1/4.
*/
public abstract class FruitDecorator implements Basket {
private Basket basket;
public FruitDecorator(Basket basket){
this.basket=basket;
}
public void show(){
basket.show();
}
}
定义各个功能组合类,对应角色中的-->ConcretorDecorator
class AppleDecorator extends FruitDecorator{
public AppleDecorator(Basket basket){
super(basket);
}
@Override
public void show() {
super.show();
System.out.println("add an apple");
}
}
class OrangeDecorator extends FruitDecorator{
public OrangeDecorator(Basket basket){
super(basket);
}
@Override
public void show() {
super.show();
System.out.println("add an orange");
}
}
class BananaDecorator extends FruitDecorator{
public BananaDecorator(Basket basket){
super(basket);
}
@Override
public void show() {
super.show();
System.out.println("add a banana");
}
}
class AppleAndBananaDecorator extends FruitDecorator{
public AppleAndBananaDecorator(Basket basket){
super(basket);
}
@Override
public void show() {
super.show();
System.out.println("add an apple and a banana");
}
}
测试
/**
* Created by zhangjiqiang on 2017/1/4.
*/
public class Test {
public static void main(String[] args) {
Basket basket=new NormalBasKet();
Basket myBasket1=new AppleDecorator(new OrangeDecorator(basket));
Basket myBasket2=new AppleDecorator(new AppleAndBananaDecorator(basket));
myBasket1.show();
myBasket2.show();
}
}
输出结果:
Paste_Image.png
网友评论