装饰模式

来源:互联网 发布:法国留学知乎 编辑:程序博客网 时间:2024/06/05 03:18

简介

装饰模式也称为包装模式,使用一种对客户端透明的方式来动态扩展对象的功能,同时也是继承关系的一种替代方案。日常生活中很多装饰模式的例子,我们穿着衣服就是对我们自己的一种装饰。

定义

动态地将责任附加到对象上。若要扩展功能,装饰着提供比继承更加有弹性的替代方案。

使用场景

  • 需要透明并且动态地扩张类的功能;
  • 当不能采用继承的方式对系统扩展或者不采用继承不利于系统扩展和维护时;

UML类图


这里写图片描述

  • Component:抽象构件
    接口或抽象类,被装饰的原始对象。

  • ConcreteComponent:具体构件
    抽象构件的基本实现,是我们要装饰的具体对象。

  • Decorator:抽象装饰类
    我们的抽象装饰类,用于给具体构件增加职责,但是具体的职责在它的子类中实现。

  • ConcreteDecorator:具体装饰类
    抽象装饰类的子类,负责向构件添加新的职责。

装饰模式简单实现

以人穿衣服为实例demo来实现如下:
点击查看

透明装饰模式

我们看看客户端的调用代码:

public class Main {    public static void main(String[] args){        Person person,personWrap;        person = new XiaoYe();        personWrap = new PersonClothWrapper(person);        personWrap.dress();    }}

我们具体类和要包装的类都可以通过定义Person接口来进行访问。客户端可以完全针对接口抽象编程。这是透明装饰模式的一种使用。

透明装饰模式可以让客户透明的使用装饰之前的对象和装饰之后的对象,无需关心它们的区别,此外,还可以对一个已经装饰过的对象多次装饰,得到更加复杂的对象。

半透明装饰模式

上面我们看了透明的方式来指定装饰者和被装饰者,现在如果我们想要客户端调用装饰者的额外添加的方法,使用上面那种方式是不能实现的,那么客户端在定义装饰者的时候要为具体的装饰者对象了,这样装饰者才可以调用额外添加的方法。
半透明装饰模式可以给系统带来更多的灵活性。但是缺点是不能对一个对象进行多次装饰。(不知道为啥)

Android中装饰模式的使用

Context实现

我们看看我们常用的Context类的这个系统的源码,它的整套设计就是一个装饰模式,基本的类图如下:


这里写图片描述

仔细一看Context的设计模式真的完全遵循装饰设计模式。

Context相关问题

我们在Activity中可以使用Context来做很多事情,对于Context我们有必要了解它的来龙去脉。

  • Activity的Context啥时候创建的,如何创建的?
    Activity的启动流程我们这里略过,看到ActivityThread的perfromLauncheActvity方法,从启动一个Activity开始看Activity的Context是如何关联上的。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        ...        ContextImpl appContext = createBaseContextForActivity(r);        Activity activity = null;        ...        try {            Application app = r.packageInfo.makeApplication(false, mInstrumentation);            ...                appContext.setOuterContext(activity);                activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config,                        r.referrer, r.voiceInteractor, window, r.configCallback);                ...        return activity;    }

看几个关键的代码,通过createBaseContextForActivity创建Context对象,然后通过appContext.setOuterContext(activity);在Context里面关联Activity然后调用activity.attach方法传入Context对象。

  • Application的Context啥时候创建,如何创建?
    就本地而言所有的这些操作都是从ActivityThread的内部的Handler H开始分发下来,看到handleBindApplication方法。
private void handleBindApplication(AppBindData data) {        ...        try {            // If the app is being launched for full backup or restore, bring it up in            // a restricted environment with the base application class.            Application app = data.info.makeApplication(data.restrictedBackupMode, null);            mInitialApplication = app;           ...    }

看到makeApplication方法里面:

public Application makeApplication(boolean forceDefaultAppClass,            Instrumentation instrumentation) {        if (mApplication != null) {            return mApplication;        }        ...        Application app = null;        ...            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);            app = mActivityThread.mInstrumentation.newApplication(                    cl, appClass, appContext);            appContext.setOuterContext(app);        ...        mActivityThread.mAllApplications.add(app);        mApplication = app;        ...        return app;    }

通过ContextImpl创建Context,调用Context的setOuterContext关联我们的Application,在创建Application的时候传入appContext对象,我们的Application可以使用Context了。

  • Service 的Context也是一样通过调用handleCreateService方法,使用上面的方式创建和绑定Context对象。
  • 应用中的Context数量?
    Application,Activity,Service一个实例都创建一个Context对象。其余两大组件没有创建Context它们间接的使用Context。

总结

  • 装饰模式优缺点

    • 优点:
      扩展一个对象的功能比继承更加灵活,不会导致类的个数急剧增加;

      可以通过动态的方式来扩展一个对象的功能,可以在运行时选择具体的装饰类;

      可以对一个对象多次装饰,可以有多种组合;
      具体的构件类与具体的装饰类可以独立变化,依据需求来增加模块而不修改之前的;

    • 缺点:
      类数量增多,我们整了一些抽象构件,具体抽象对象,抽象装饰类,具体装饰类;

      对于多次装饰的时候,排错会更加困难;

  • 装饰模式和代理模式对比

    代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能,仅此而已

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 偷渡后国内资产怎么办 手机系统太低怎么办 拍古装是短发怎么办 吞下一个李子核怎么办? 宝宝吞了荔枝核怎么办 美吉姆培训不过怎么办 1岁宝宝挑食怎么办 宝宝不愿意开口说话怎么办 自闭症孩子不爱学习怎么办 宝宝不独立走路怎么办 六个月宝宝不认人怎么办 小孩隔奶奶涨怎么办 小孩段奶奶涨怎么办 1岁半还不会说话怎么办 孩子嗓子哑了怎么办 小朋友嗓子哑了怎么办 4周岁宝宝拉肚子怎么办 小孩不肯拉小便怎么办 做销售不爱说话怎么办 我伤害了朋友怎么办 三岁发音不准怎么办 心里憋不住话怎么办 自己不长记性怎么办 孩子不愿意开口说话怎么办 孩子不爱开口说话怎么办 宝宝犟脾气不好怎么办 小孩说话不算话怎么办 孩子说话不算话怎么办 孩子故意不好好说话怎么办 小孩说话吐字不清楚怎么办 腿老是抽筋是怎么办 半夜睡觉脚抽筋怎么办 我不爱说话内向怎么办 小孩子吐字不清怎么办 宝宝前边头发少怎么办 宝宝咬嘴唇龅牙怎么办 小孩老是咬下唇怎么办 五月小孩掉下床怎么办 小孩说话夹舌头怎么办 小孩自闭不说话怎么办 孩子突然不说话怎么办