一文带你理解装饰模式

装饰模式也叫包装模式,是一种结构型设计模式,主要是提供一种扩展类功能的方式。在安卓世界中,许多带有wrapper字符串的类名都运用了这种设计模式。

定义

不采用生成子类的方式,透明并且动态的给一个类添加额外的功能

场景

  1. 需要透明且动态的扩展一个类的功能时

角色

抽象组件

被装饰的原始类,可以是一个接口或者抽象类

具体组件

被装饰的原始类的具体实现

抽象装饰者

装饰组件的类,一般是抽象类,继承自抽象组件,并且持有一个抽象组件的引用

具体装饰者

抽象装饰者的具体实现,装饰关系较简单时,抽象装饰者和具体装饰者可以由一个类实现

代码说明

在大多数情况下,抽象包装者和具体包装者是由一个类来承担。这样可以省略抽象包装者,减少类文件数量。下面我们来看下一个场景的实现。
一个组件有一个jump方法,只是简单输出一句话,我们想通过装饰者模式在该方法的调用前后输出一条语句。下面来看一下具体的实现。

首先我们定义一个抽象组件接口,接口内有一个jump方法。

/**
 * 抽象组件接口
 */
public interface IComponent {

  /**
   * 需要包装的方法
   */
  void jump();
}

然后通过实现的方式来创建具体需要被装饰的类

/**
 * 组件具体实现类
 */
public class ComponentImpl implements IComponent {
  /**
   * 需要包装的具体方法
   */
  @Override public void jump() {
    System.out.println("调用具体组件类的方法");
  }
}

最后,是我们的装饰类。

/**
 * 装饰对象类
 */
public class ComponentWrapper implements IComponent {

  private IComponent realComponent;

  /**
   * 需要装饰的方法
   */
  @Override public void jump() {
    step1();
    realComponent.jump();
    step2();
  }

  /**
   * 装饰1
   */
  protected void step1() {
    System.out.println("方法前面调用包装类的包装方法1");
  }

  /**
   * 装饰2
   */
  protected void step2() {
    System.out.println("方法后面调用包装类的包装方法2");
  }
}

我们来看下具体使用。假设原始组件需要调用jump方法。包装后,可以这样调用。

 public static void main(String[] args) {
    // 包装前调用
    ComponentImpl component = new ComponentImpl();
    component.jump();

    // 装饰后调用
    ComponentWrapper wrapper = new ComponentWrapper(component);
    wrapper.jump();
  }

在装饰前,调用原始对象的jump方法,只会打印

	调用具体组件类的方法

而装饰后,则会打印

    方法前面调用包装类的包装方法1
    调用具体组件类的方法
    方法后面调用包装类的包装方法2
    

这样,在方法一和方法二中就可以扩展组件具体实现类的jump方法。

关于安卓源码

开篇说过,在安卓世界中,许多带有wrapper字符串的类名都运用了这种设计模式。比如ContextWrapperContextThemeWrapper等,这种形式的装饰可以为类提供额外的功能,同时,将包装方法的部分装饰逻辑以抽象方法的形式进行写入,那么子类就可以进行更加简单的方法装饰。

总结

装饰模式是一种扩展类功能的设计模式,与代理模式有些相似。代理模式是通过代理的方式来控制类的访问等,而装饰模式是为类提供额外的功能,在某种程度上,是继承的一种替代品。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值