菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
28
0

装饰者模式

原创
05/13 14:22
阅读数 78974

一、概述

一般问题:由于需求扩张需要对现有的对象添加新的功能。

核心方案:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比继承更加灵活。

设计意图:装饰者模式允许向一个现有的对象添加新的功能,同时又不改变其结构。其原理是将新增功能封装在装饰类中,其次,装饰类必然知道被装饰类,否则新增功能就无从谈起。实际上,装饰类就是被装饰类的一层包装。同代理模式非常相似,装饰类和被装饰类也需要实现同一个接口。

 


 二、应用场景

在Android系统中,基础组件Context的架构设计就采用了装饰者模式。

 

Context中声明了非常多的抽象方法,为了方便讲解,我们只取其中两个来做说明。

Context抽象类定义如下:

public abstract class Context {
      public abstract void startActivities(Intent[] intents);
      public abstract boolean bindService(Intent service, ServiceConnection conn, int flags);
}

ContextImpl实现类:

class ContextImpl extends Context {
    
            @Override
        public void startActivities(Intent[] intents) {
            warnIfCallingFromSystemProcess();
            startActivities(intents, null);
        }
    
            @Override
        public boolean bindService(Intent service, ServiceConnection conn, int flags) {
            warnIfCallingFromSystemProcess();
            return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), Process.myUserHandle());
        }    
    }

ContextWrapper装饰基类,只是对ContextImpl类简单的封装,没有添加新的功能;装饰实体类Activity则扩展了很多新功能,比如,生命周期相关函数等。

  public class ContextWrapper extends Context {
    
            Context mBase; //定义实现类变量
            protected void attachBaseContext(Context base) {
            if (mBase != null) {
                throw new IllegalStateException("Base context already set");
            }
            mBase = base; //为实现类变量赋值
        }
    
            @Override
        public void startActivities(Intent[] intents) {
            mBase.startActivities(intents); //由实现类具体执行startActivities任务
        }
    
            @Override
        public boolean bindService(Intent service, ServiceConnection conn, int flags) {
            return mBase.bindService(service, conn, flags); //由实现类具体执行bindService任务
        }
    }

分析上面代码:

  1. ContextImpl和ContextWrapper都继承自Context抽象类,且重写了其声明的抽象方法。
  2. ContextWrapper是ContextImpl的装饰类,其属性mBase即ContextImpl实例,在实现方法中直接调用mBase同名方法。
  3. Acivity是装饰实体类,对ContextImpl进行了功能扩展,实际上ContextImpl的装饰类还有Application和Service。

三、总结

总结:装饰者模式是一种结构型设计模式,也称为包装模式。它使用对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一,但比继承更加灵活。

用一句话来形容装饰者模式就是:

“一奶同胞,一个实干,一个外包”

优点:可以动态扩展一个现有类的功能,比继承更加灵活

缺点:它会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂

 

发表评论

0/200
28 点赞
0 评论
收藏
为你推荐 换一批