安卓设计模式(四)装饰者模式

作者: uncochen | 来源:发表于2016-11-01 17:46 被阅读0次

    本文将讨论Java设计模式中比较重要的模式之一:装饰者模式

    该系列其他文章:

    装饰者模式

    装饰者模式也称为包装模式,属于结构型设计模式

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

    使用场景:需要透明且动态的地扩展类的功能时.

    UML类图

    包括以下几个角色:

    • 抽象构件(Component)角色:给出一个抽象接口,规范待装饰者的功能方法。
    • 具体构件(ConcreteComponent)角色:待装饰类。
    • 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
    • 具体装饰(ConcreteDecorator)角色:具体装饰者。

    举例

    Component:抽象组件

    /**
     * =================中康================
     *
     * @Author: 陈振
     * @Email : 18620156376@163.com
     * @Time : 2016/11/1 14:36
     * @Action :待装饰者抽象:开发者
     *
     * =================中康================
     */
    public abstract class Coder {
        public abstract void dev();//开发公司项目
    }
    

    ConcreteComponent:具体组件

    /**
     * =================中康================
     *
     * @Author: 陈振
     * @Email : 18620156376@163.com
     * @Time : 2016/11/1 14:38
     * @Action :待装饰者具体实现:安卓开发一枚
     *
     * =================中康================
     */
    public class AndroidCoder extends Coder {
        @Override
        public void dev() {
            Log.i("AndroidCoder", "开发公司的安卓项目");
        }
    } 
    

    Decorator:装饰者抽象

    /**
     * =================中康================
     *
     * @Author: 陈振
     * @Email : 18620156376@163.com
     * @Time : 2016/11/1 14:42
    * @Action :装饰者抽闲:具有维护开源项目的增强型功能
     *
     * =================中康================
     */
    public abstract class OpenSource extends Coder {
        private Coder mCoder;
    
        public OpenSource(Coder coder) {//注意这里,装饰者会持有待装饰者组件的实例
            mCoder = coder;
        }
    
        public abstract void fixBug();//修复开源项目中的bug
    
        @Override
        protected void dev() {
            mCoder.dev();
        }
    } 
    

    ConcreteDecorator:具体装饰者

    /**
     * =================中康================
     *
     * @Author: 陈振
     * @Email : 18620156376@163.com
     * @Time : 2016/11/1 14:44
     * @Action :装饰者,具有修复github上项目的bug的功能
     *
     * =================中康================
     */
    public class GithubFixer extends OpenSource {
        public GithubFixer(Coder coder) {
            super(coder);
        }
    
        @Override
        public void fixBug() {
            Log.i("GithubFixer", "修复github上的bug");
        }
    
        @Override
        public void dev() {
            fixBug();//上班之前先看看开源项目有没有bug需要修复
            super.dev();//再开始开发
        }
    } 
    

    实际使用

        AndroidCoder androidCoder = new AndroidCoder();//安卓开发者
    
        androidCoder.dev();//以前每天上班就是写代码
    
        //装饰者模式之后
        GithubFixer githubFixer = new GithubFixer(androidCoder);//公司项目没那么紧,每天开发之前可以先维护下开源项目
        githubFixer.dev();
    
        new GithubFixer(androidCoder).dev();//与以上等价
    

    结果:

    AndroidCoder: 修复github上的bug
    GithubFixer:开发公司的安卓项目
    

    分析

    在这个例子中,安卓程序猿一天的工作就是开发公司的项目,即androidCoder.dev(),后来想要增强自己的功能,需要维护github上的开源项目,于是便使用了GithubFixer来装饰自己,即:new GithubFixer(androidCoder).dev(),这样在每次每天开发之前都会去先维护开源项目,再去开发.

    1. 对于调用者,这完全是透明的,在所有基础调用的位置,做以下替换就可以:

       androidCoder.dev();//==>
      
       new GithubFixer(androidCoder).dev();
       //当然也可以维护更多社区的项目...
       new OsChinaFixer(androidCoder).dev();
      
    2. 另外,GithubFixer不仅仅可以装饰androidCoder,IosCoder-JavaCoder等等都可以装饰,例如:

       new GithubFixer(iosCoder).dev();
       new GithubFixer(phpCoder).dev();
      
    3. 如果你使用继承来为AndroidCoder(ios-php等等)增加fixBug功能,组件类别比较多的情况下,势必会造成体系的臃肿,但是反观装饰者模式,由于是动态的为组价增强功能,则很好的避免了继承体系臃肿的问题.

    4. 装饰者模式可以链式调用,例如:

       new PlayGame(new GithubFixer(iosCoder)).dev;//为组件增加维护开源项目,打游戏的功能
      
    5. 组件的原有功能没有任何破坏,Coder.dev()保持内部逻辑;

    6. 装饰者内部会持有待装饰者组件实例

    Android源码中装饰者模式的使用

    在源码中装饰者模式被使用的地方还是很多的,最典型的是Context体系,这里简单分析一下:

    • Context - 抽象组件
    • ContextImpl - 具体组件:继承自Context,实现了Context中的抽象方法;
    • ContextWrapper - 装饰者抽象:继承Context,定义了一些增强方法,内部持有Context引用
    • ContextThemeWrapper - 具体装饰者父类:实现了ContextWrapper中的抽象方法,提供一些通用实现
    • Activity,Service,Application - 具体装饰者实现类:实现全部的装饰方法

    关于作者

    相关文章

      网友评论

        本文标题:安卓设计模式(四)装饰者模式

        本文链接:https://www.haomeiwen.com/subject/bzimuttx.html