《Android源代码设计模式解析与实战》读书笔记(二十一)

第二十一章、装饰模式

装饰模式也称为包装模式。是结构型设计模式之中的一个。装饰模式是一种用于替代继承技术的一种方案。

1.定义

动态的给一个对象加入一些额外的职责。就添加功能来说。装饰模式相比生成子类更为灵活。

2.使用场景

(1)须要透明且动态地扩展类的功能时。且在不影响其它对象的情况下。

(2)当不能採用继承对系统进行扩展时能够使用装饰模式。比方final类。

3.UML类图

这里写图片描写叙述

(1)Component:抽象组件。

能够是一个接口或抽象类。其充当的就是被装饰的原始对象。

(2)ConcreteComponent:组件详细实现类,该类是Component类的基本实现,也是我们装饰的详细对象。

(3)Decorator:抽象装饰者。其职责就是装饰我们的组件对象,通过其子类扩展该方法以达到装饰的目的。其内部一定要有一个指向组件对象的引用。在大多数情况下。该类为抽象类。须要依据不同的装饰逻辑实现不同的详细子类。

(4)ConcreteDecoratorAConcreteDecoratorB:装饰着详细实现类。负责向构件加入新的职责。

4.简单实现

以一个男孩穿衣装扮为例。实现给男孩在家与出门的穿衣装扮。

抽象组件类(Component):

public abstract class Person {
    /**
     * Person下有一个穿着的抽象方法 
     */
    public abstract void dressed();
}

详细实现类(ConcreteComponent):表示要装扮的Boy

public class Boy extends Person{

    @Override
    public void dressed() {
        System.out.println("Boy穿了内衣内裤");
    }

}

抽象装饰类(Decorator):PersonCloth 表示人所穿着的衣服

public class PersonCloth extends Person{

    protected Person mPerson; //保持一个Person类的引用

    public PersonCloth(Person mPerson) {
        super();
        this.mPerson = mPerson;
    }

    @Override
    public void dressed() {
        mPerson.dressed();
    }
}

出门穿的衣服:

public class OutsideCloth extends PersonCloth{

    public OutsideCloth(Person mPerson) {
        super(mPerson);
    }

    /**
     * 穿短袖 
     */
    private void dressShirt(){
        System.out.println("穿件短袖");
    }

    /**
     * 穿牛仔裤 
     */
    private void dressJean(){
        System.out.println("穿牛仔裤");
    }

    /**
     * 穿鞋子 
     */
    private void dressShoes(){
        System.out.println("穿鞋子 ");
    }

    @Override
    public void dressed() {
        super.dressed();
        dressShirt();
        dressJean();
        dressShoes();
    }

}

在家穿的衣服:

public class HomeCloth extends PersonCloth{

    public HomeCloth(Person mPerson) {
        super(mPerson);
    }

    /**
     * 穿短裤
     */
    private void dressShorts(){
        System.out.println("穿短裤");//在家里随便点
    }

    @Override
    public void dressed() {
        super.dressed();
        dressShorts();
    }

}

装扮:

public class Client {
    public static void main(String[] args) {
        //首先有一个男孩
        Person person = new Boy();

        //在家
        PersonCloth personCloth = new HomeCloth(person);
        personCloth.dressed();
        System.out.println("--------------");
        //出门
        PersonCloth personCloth1 = new OutsideCloth(person);
        personCloth1.dressed();

    }
}

结果

Boy穿了内衣内裤
穿短裤
--------------
Boy穿了内衣内裤
穿件短袖
穿牛仔裤
穿鞋子 

5.Android源代码中的实现

1.Context

Context类在Android中被称为“上帝对象”,它的本质就是一个抽象类,在装饰模式中相当于抽象组件。而在内部定义了大量的抽象方法。比方我们经经常使用到的startActivity方法。

而真正实现是在ContextImpl中完毕,那么ContextImpl 就是详细实现类。由于ContextWrapper 继承于Context ,所以ContextWrapper 就是装饰者。

详细大家能够自行查看源代码。

6.差别

1.与代理模式的差别

(1)装饰模式是以对client透明的方式扩展对象的功能,是继承方案的一个替代。而代理模式则是给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用。

(2)装饰模式应该为所装饰的对象增强功能;代理模式是对代理对象施加控制,不正确对象本身功能进行增强。

2.与适配器模式的差别

适配器模式是用新接口来调用原接口,原接口对新系统是不可见的;装饰模式增强了其它对象的功能而同一时候又不改变它的接口。

7.总结

在实际开发中我们应该写过例如以下代码:事实上这些新增方法的调用就相似装饰模式中的装饰者的职责。仅仅只是这里我们没有保持对组件类的引用。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化数据
        initData();

        //初始化控件
        initViews();

        //初始化事件
        initEvent();
    }

1.长处

(1)对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧添加。

(2)能够通过一种动态的方式在执行时选择不同的详细装饰类,从而实现不同的行为。

(3)能够对一个对象进行多次装饰。通过使用不同的详细装饰类以及这些装饰类的排列组合,能够创造出非常多不同行为的组合。得到功能更为强大的对象。

(4)详细构件类与详细装饰类能够独立变化。用户能够依据须要添加新的详细构件类和详细装饰类,原有类库代码无须改变。符合“开闭原则”。

2.缺点

(1)使用装饰模式进行系统设计时将产生非常多小对象,这些对象的差别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象的产生势必会占用很多其它的系统资源,在一定程序上影响程序的性能。

(2)对于多次装饰的对象,调试时寻找错误可能须要逐级排查,较为繁琐。

8.參考

1. 设计模式(结构型)之装饰者模式

原文地址:https://www.cnblogs.com/gavanwanggw/p/7307322.html