• 《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. 设计模式(结构型)之装饰者模式

  • 相关阅读:
    js对象与字符串相互转换
    11 ~ express ~ 解决 cookie 中文报错的问题
    10 ~ express ~ 使用 cookie 保存用户 信息
    href="javacript:;" href="javacript:void(0);" href="#"区别。。。
    9 ~ express ~ 用户注册
    8 ~ express ~ 基于数据库的验证
    SpringBoot整合RocketMQ
    RabbitMQ(五)消息发送失败后的处理
    分享一些JVM常见的面试题(转)
    双亲委派模型
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7307322.html
Copyright © 2020-2023  润新知