设计模式-装饰模式

本文详细介绍了装饰模式的概念及其优点,展示了如何使用装饰模式动态地给一个对象添加职责,并提供了具体的Java代码示例,包括抽象构件、具体构件、装饰角色及具体装饰角色的实现。

这里写图片描述

装饰模式定义

装饰模式是一种比较常见的模式,其定义如下:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

优点

  • 装饰类和被装饰类可以独立发展,而不会相互耦合。Component类无须知道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具体的构件。
  • 装饰模式是继承关系的一个替代方案。不管装饰多少层,返回的对象还是Component,实现的还是is-a的关系。
  • 装饰模式可以动态地扩展一个实现类的功能。注意是动态。
  • 装饰模式是对继承的有力补充。使用装饰模式可以实现易维护,易扩展,易复用等。在一些情况下使用继承就会增加很多子类,而且灵活性很差,当然维护也不容易了,也就是说装饰模式可以替代继承,解决我们类膨胀的问题。同时还有一个重要的区别,继承是静态地给类增加功能,而装饰模式是动态地增加功能。

    注意:尽量减少装饰类的数量,以便降低系统的复杂度。

    使用场景

  • 需要扩展一个类的功能,或给一个类增加附加功能。
  • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
  • 需要为一批的兄弟类进行改装或加装功能,首选装饰模式。
  • 模式框架

    装饰模式的通用类图如上图所示。
    在类图中,有四个角色需要说明:

  • Component抽象构件
    Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象。
    注:在装饰模式中,必然有一个最基本,最核心,最原始的接口或抽象类充当Component抽象构件。
  • ConcreteComponent具体构件
    ConcreteComponent是最核心,最原始,最基本的接口或抽象类的实现,要装饰的就是这个对象。
  • Decorator装饰角色
    一般是一个抽象类。实现接口或抽象方法,它里面可不一定有抽象的方法,在它的属性里必然有一个private变量指向Component抽象构件。
  • 具体装饰角色
    ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类,你要把你最核心,最原始,最基本的东西装饰城其他东西。
  • 代码:

    /*
     * 抽象构件
     */
    public interface Component {
        public void operate();
    }
    
    /*
     * 具体构件
     */
    public class ConcreteComponent implements Component{
        //具体实现
        public void operate() {
            // TODO Auto-generated method stub
            System.out.println("Do something");
        }
    }
    
    /*
     * 抽象装饰者
     */
    public abstract class Decorator implements Component{
        private Component component=null;
    
        //通过构造函数传递被修饰者
        public Decorator(Component component){
            this.component=component;
        }
    
        //委托给被修饰者执行
        public void operate(){
            this.component.operate();
        }
    }
    
    /*
     * 具体装饰者1
     */
    public class ConcreteDecorator1 extends Decorator{
        //定义被修饰者 调用父类的构造函数
        public ConcreteDecorator1(Component component) {
            super(component);
        }
    
        //定义自己的修饰方法
        private void method1(){
            System.out.println("method1 修饰");
        }
    
        //重写父类的Operation方法
        @Override
        public void operate(){
            this.method1();
            super.operate();
        }
    }
    
    /*
     * 具体装饰者2
     */
    public class ConcreteDecorator2 extends Decorator{
        //定义被修饰者 调用父类的构造函数
        public ConcreteDecorator2(Component component){
            super(component);
        }
    
        //定义自己的修饰方法
        private void method2(){
            System.out.println("method2修饰");
        }
    
        //重写父类的Operation方法
        @Override
        public void operate(){
            super.operate();
            this.method2();
        }
    }
    
    /*
     * 场景类
     */
    public class Client {
    
        public static void main(String[] args){
            Component component=new ConcreteComponent();
            //第一次修饰
            component=new ConcreteDecorator1(component);
            //第二次修饰
            component=new ConcreteDecorator2(component);
            //修饰后运行
            component.operate();
        }
    }
    

    运行结果:
    method1 修饰
    Do something
    method2修饰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值