Java设计模式之装饰器模式

装饰器模式

介绍

装饰器模式(Decorator Pattern)指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰类来包装原有的类,并提供额外的功能。

引入问题

举个例子,某公司拥有一众程序员。

public class Coder() {
    public void code() {
        System.out.println("会写代码的程序员...");
    }
}

现在,业务需要有Java语言code能力的程序员。按照面向对象的设计思想,一般的做法是新增一个JavaCoder类,继承Coder类

public class JavaCoder extends Coder {
    public void codeJava() {
        System.out.println(" 会使用Java语言....");
    }
}

然后,又需要有Go语言code能力的程序员,照例需要新添加一个GoCoder类,继承Coder类

public class GoCoder extends Coder {
    public void codeGo() {
        System.out.println(" 会使用Go语言....");
    }
}

这时,如果现在需要既有Java语言code能力,又有Go语言code能力的程序员,又需要创建一个JavaAndGoCoder类,这样就会导致一旦有需求增加或变更,类数量就会暴增。如果已经存在的类能复用就好了。

解决方案

装饰器模式就是为了解决上述问题而生的。它通过把复杂的功能简单化,分散化,然后在运行期间,根据需要来动态组合。装饰器模式的通用类图如下:
装饰器模式类图
在装饰器模式中一共有以下四种角色

  • Component
    增加功能时的核心角色。负责定义功能接口。
  • ConcreteComponent
    实现Component角色所定义的接口。
  • Decorator
    该角色与Component角色有相同的接口,且在该角色内保存了Component角色。
  • ConcreteDecorator
    该角色是Decorator角色的具体实现。

以上述程序员的问题为例,我们使用装饰器模式为Coder类动态添加方法

  • Coder类(扮演Component角色)
    public abstract class Coder { 
    public abstract void code();
    }
  • ConcreteCoder类(扮演ConcreteComponent角色)
    public class ConcreteCoder extends Coder { 
    @Override
    public void code() {
    System.out.println("会写代码的程序员...");
    }
    }
  • CoderDecorator类(扮演Decorator角色)
    public abstract class CoderDecorator extends Coder { 
    private Coder coder;
    public CoderDecorator(Coder coder) {
    this.coder = coder;
    }
    @Override
    public void code() {
    coder.code();
    }
    }
  • JavaCoder类(扮演ConcreteDecorator角色)
    public class JavaCoder extends CoderDecorator { 
    public JavaCoder(Coder coder) {
    super(coder);
    }
    public void codeJava() {
    System.out.println("用Java语言写代码...");
    }
    @Override
    public void code() {
    super.code();
    codeJava();
    }
    }
  • GoCoder类(扮演ConcreteDecorator角色)
    public class GoCoder extends CoderDecorator { 
    public GoCoder(Coder coder) {
    super(coder);
    }
    public void codeGo() {
    System.out.println("用Go语言写代码...");
    }
    @Override
    public void code() {
    super.code();
    codeGo();
    }
    }

此时,当我们需要既有Java语言code能力,又有Go语言code能力的程序员时,只要用CoderDecorator类和CoderDecorator类去装饰ConcreteCoder类就行了,而不需要再新增类。

  • 调用类

    public class Client {
        public static void main(String[] args) {
            Coder coder = new GoCoder(new JavaCoder(new ConcreteCoder()));
            coder.code();
        }
    }
  • 输出结果

    会写代码的程序员...
    用Java语言写代码...
    用Go语言写代码...
    

到此,我们就通过装饰器模式实现了功能的动态增加。

装饰器模式总结
  • 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
  • 缺点:多层装饰比较复杂。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值