java设计模式---装饰器模式

装饰器模式概述

设计模式理解

装饰器模式,属于比较难以理解的一种设计模式,如果直接上代码,可能无法深刻体会到这个设计模式所蕴含的精髓所在。我们学习一个模式,需要从思想上进行理解,从使用场景上进行比对。

顾名思义,这个模式的核心思想,是用于对一个已有的类进行功能增强,我们可以进行通俗的理解:
如果只有一块布,那么这块布做的衣服只是为了保暖的普通衣服。但是在衣服的基础上,染上金黄色,那么这个衣服便是一件皇家衣服,只要是皇家的人,才能穿,具备了特殊的属性。如果在黄色的基础上,再秀上一条龙,那么这个衣服就成了皇帝专用的龙袍。

上述举得例子,体现了对一个已有的类的功能的增强,装饰器模式的特性不仅仅体现在功能增强,也体现在增强的功能具备灵活性,比如:往没有颜色的衣服上先秀一条龙,那么也许是给太子穿的,再往有龙的衣服上再染黄色,那么也许就是太子升级当上皇帝了。从这里可以看出。装饰模式的装饰顺序,是可以根据具体的业务需要进行灵活变更,而无需修改原始类的任何代码。

装饰器模式的实现过程
  1. 定义一个rule接口(抽象类),定义核心业务的执行方法,比如上面例子中,我们可以理解为做衣服
  2. 新增一个类,直接实现接口,用来实现基本的业务功能,使用普通布料做衣服
  3. 核心动作:定义一个Decorator类抽象,实现做衣服接口方法。
    同时需要持有一个私有的rule接口成员属性,对这个属性使用本身的构造函数进行初始化,在自身实现rule接口的方法中,再次调用rule接口方法。
    进一步理解下为什么要这么做:当Decorator类的子类进行向上初始化时,这个Decorator类因为符合rule接口规范,所以他持有的rule接口属性,就充当了子类对象容器的角色,而且每多一层子类调用,这个容器所包含的子类信息会越多,可以在后面的代码中进一步体会。
  4. 定义具体的装饰器实现类,继承Decorator类,实现功能增强的业务逻辑,用来扩充基本的业务功能,在子类中,核心是需要使用super关键字对父类(Decorator)进行向上调用,便可以实现对被传入的接口实例的方法调用,当父类构造函数中的被传入的接口实例中,持有多层接口实例(就是子类对象容器),那么这个rule接口方法调用将进行逐层调用,最终效果是可以实现链式传递调用
装饰器模式的特点
  1. 在不修改原始类的条件下,增强原始类的调用
  2. 相比于策略模式,具备极好的灵活性,子类的数量可控,在复杂的业务条件下依然可以保证子类数量不出现爆炸性增长

代码实现

代码实现

采用上面讲的衣服的例子进行示例

定义一个衣服的接口

/*
* 定义基础接口,用来规范所有的行为动作,为后续的逐步包装定义标准
*
* 这个接口也是被装饰的对象
* */

public interface Clothes {

    public void weaveClothes();

}

使用普通的布料完成这个衣服的基本工序

/*
* 后续所有的装饰器的功能,都是为了以这个类的功能作为拓展(思想上)
* */

public class BaseClothes  implements Clothes{

    @Override
    public void weaveClothes(){

        System.out.println("使用布料进行衣服织造。");
        System.out.println("完成普通的布料衣服织造。");

    }

}

定义Decorator类型,规范衣服后续工序的织造流程

/*
* 这个类是装饰类的超类,主要用于规范后续新增装饰类调用被装饰对象的规则
*
* 装饰规则:Decorator抽象类中,持有Clothes接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。
* */
public abstract class Decorator implements Clothes{

    private Clothes clothes;

    public Decorator(Clothes clothes){
        this.clothes = clothes;
    }

    @Override
    public void weaveClothes(){
        clothes.weaveClothes();
    }

}

第一道工序,染色操作

public class DecoratorColour extends Decorator{

    public DecoratorColour(Clothes clothes){

        super(clothes);

    }

    public void colourStart(){
        System.out.println("开始对衣服进行明黄色处理");
    }
    public void colourEnd(){
        System.out.println("处理染色工序完成完成,衣服是黄色的。");
    }

    @Override
    public void weaveClothes(){
        super.weaveClothes();
        colourStart();
        colourEnd();
    }

}

第二道工序,往衣服上绣上龙

public class DecoratorDragon extends Decorator {

    public DecoratorDragon(Clothes clothes){
        super(clothes);
    }

    public void showDragonStart(){
        System.out.println("开始手工进行绣龙工序,这个技术需要很高超的技巧");
    }
    public void showDragonEnd(){
        System.out.println("龙已经绣到了衣服上,效果相当逼真,活灵活现。");
    }

    @Override
    public void weaveClothes(){
        super.weaveClothes();
        showDragonStart();
        showDragonEnd();
    }

}

客户端调用代码

public class DecoratorContextDemo {

/*
* 调用顺序可以任意组合,实现不同的效果
* */

    @Test
    public void decoratorContextTest(){

        Clothes clothes = new BaseClothes();

//先染色再绣龙
        Decorator decorator = new DecoratorDragon(new DecoratorColour(clothes));
//先绣龙再染色
        Decorator decorator1 = new DecoratorColour(new DecoratorDragon(clothes));

        System.out.println("----先染色,再绣龙----");
        decorator.weaveClothes();
        System.out.println("====================");
        System.out.println("----先绣龙,再染色----");
        decorator1.weaveClothes();

    }


}

执行结果:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值