文章

设计模式:装饰模式或包装模式

文章目录

什么是设计模式

装饰模式又名包装模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

有透明和半透明两种,大部分都是半透明的,半透明的装饰模式是介于装饰模式和适配器模式之间的。

装饰模式的核心:功能扩展。

透明和半透明的区别:

透明的装饰模式,要求具体构件角色、装饰角色的接口与抽象构件角色的接口完全一致。意思是奶茶接口、珍珠奶茶和蜂蜜奶茶、调料的这些接口一样。下面代码中会有体现。相反,如果装饰角色的接口与抽象构件角色接口不一致,那就是半透明的了。

优缺点

优点
  1. 动态扩展类功能,比类继承灵活,且对客户端透明;
  2. 继承关系的一种替代方案。相比与类继承的父子关系,装饰模式更像是一种组合关系(is-a);
  3. 可以对同一个被装饰对象进行多次装饰,创建出不同行为的复合功能;
缺点
  1. 多层装饰比较复杂(灵活的同时会带来复杂性的增加);
  2. 装饰嵌套过多,会产生过多小对象(每个装饰层都创建一个相应的对象);
  3. 装饰嵌套过多,易于出错,且调试排查比较麻烦(需要一层一层对装饰器进行排查,以确定是哪一个装饰层出错);

装饰模式UML

抽象组件(Component):

可以是一个接口或者抽象类,其充当被装饰类的原始对象,规定了被装饰对象的行为;

具体组件(ConcreteComponent):

实现/继承 Component 的一个具体对象,也即被装饰对象;

抽象装饰器(Decorator):

通用的装饰ConcreteComponent的装饰器,其内部必然有一个属性指向Component抽象组件;其实现一般是一个抽象类,主要是为了让其子类按照其构造形式传入一个Component抽象组件,这是强制的通用行为(当然,如果系统中装饰逻辑单一,并不需要实现许多装饰器,那么我们可以直接省略该类,而直接实现一个具体装饰器(ConcreteDecorator) 即可);

具体装饰器(ConcreteDecorator):

Decorator 的具体实现类,理论上,每个 ConcreteDecorator 都扩展了 Component 对象的一种功能;

总结:

装饰模式 角色分配符合设计模式里氏替换原则,依赖倒置原则,从而使得其具备很强的扩展性,最终满足开闭原则。

代码实现

Component抽象类

Component是一个接口或是抽象类,就是定义我们最核心的对象,也就是最原始的对象。

    /**
     * 抽象类
     */
    public abstract class Conpontent {
        public abstract void operation();
    }

ConretetComponent类

具体构件,通过继承实现Component抽象类中的抽象方法。是最核心、最原始、最基本的接口或抽象类的实现,我们要装饰的就是它。

    /**
     * 实现Component的抽象方法
     */
    public class ConcreteComponent extends Conpontent {

        @Override
        public void operation() {
            Log.d(TAG, " ConcreteComponent operation : ");
        }
    }
Decorator装饰类

一般是一个抽象类,在其属性里必然有一个private变量指向Component抽象构件。

    /**
     * 装饰者类
     */
    public abstract class Decorator extends Conpontent {
        private Conpontent conpontent = null;

        public Decorator(Conpontent conpontent) {
            this.conpontent = conpontent;
        }

        @Override
        public void operation() {
            if (null != conpontent) {
                conpontent.operation();
            }
        }
    }

ConcreteDecorator类

可以写多个具体实现类,把最核心的、最原始的、最基本的东西装饰成其它东西。

如下写两个类ConcreateDecoratorA和ConcreateDecoratorB。

    /**
     * 装饰者具体实现类A
     */
    public class ConcreateDecoratorA extends Decorator {

        public ConcreateDecoratorA(Conpontent conpontent) {
            super(conpontent);
        }

        private void method() {
            Log.d(TAG, "ConcreateDecoratorA method : ");
            return;
        }

        @Override
        public void operation() {
            super.operation();
            this.method();
        }
    }
    /**
     * 装饰者具体实现类B
     */
    public class ConcreateDecoratorB extends Decorator {

        public ConcreateDecoratorB(Conpontent conpontent) {
            super(conpontent);
        }

        private void method() {
            Log.d(TAG, "ConcreateDecoratorB method : ");
            return;
        }

        @Override
        public void operation() {
            super.operation();
            this.method();
        }
    }
 Conpontent conpontent = new ConcreteComponent();
 conpontent = new ConcreateDecoratorA(conpontent);
 conpontent= new ConcreateDecoratorB(conpontent);
 conpontent.operation();

摘抄

  1. 大话设计模式
  2. 装饰模式
  3. 简说设计模式——装饰模式
  4. 深入分析设计模式中的装饰模式(java代码实现)

猜你喜欢

本文作者:刘伟 http://blog.csdn.net/lovelion 类与类之间的关系(1) 在软件系统中,类并不是孤立存在的,类与类之间存在各种关系,对于不同类型的关系,UML提供了不同的表示方式。       1. 关联关系 关联…

UML类图中属性的可见性分为4级 public 公用的 :用+ 前缀表示 ,该属性对所有类可见 protected 受保护的:用 #  前缀表示,对该类的子孙可见 private 私有的:用- 前缀表示,只对该类本身可见 package 包…
发表评论