前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式---装饰器模式

设计模式---装饰器模式

作者头像
技术文章精选
发布2022-11-08 16:33:50
2660
发布2022-11-08 16:33:50
举报
文章被收录于专栏:优质文章优质文章

简述

运行时,为原对象拓展新的行为。

相较于传统的继承来拓展新的行为,装饰器模式更为的灵活多变,当然实现起来也更为复杂。

话不多说,看个优化案例吧。

优化案例

最初版v0

现有系统中有设定窗口Style的模块,现在想增加一个圆角的样式。以下是现有模块的代码。

代码语言:javascript
复制
class Style {    public void style() {        System.out.println("设置Order");    }}

第一种传统的修改方式。

代码语言:javascript
复制
class Style {    public void style() {        System.out.println("设置Order");        System.out.println("设置Radius");    }}

虽然代码简单,但细想一下,如果我们日后仍然需要单独设置Order的样式怎么办。现在的代码实现已经无法满足了不是?

为此,我们可能会想到另一种方案。使用继承。

代码语言:javascript
复制
class BaseStyle {    public void style() {        System.out.println("设置Order");    }}class Radius extends BaseStyle {    public void style() {        super.style();        System.out.println("设置Radius");    }}

确实,如果不在意类的命名的话,目前来看这确实是个好的选择。请注意,只是目前来看。设计不只着眼与当前,而是需要放眼未来。什么意思呢?比如,当未来需要添加一个Color样式的时候怎么办,有人可能认为添加再添加一个BassStyle类的子类Color就好了;如果客户就只要一个单独的Color样式呢,或者说需要一个可以设置Radius和Color的样式。再超前一些,客户如果想要的是增加一个样式,且可以与现有的任何一种或多种样式随意组合呢?又该怎么办?传统的继承已经搞不了了呀。

别慌,最后这一种需求正好就是使用装饰器模式的目的。我们来看看改进后的案例吧。

修改版v1

使用装饰器模式优化上述需求,使得任意样式间可以任意组合,这种任意组合包括任意种类和数量。

代码语言:javascript
复制
public interface Style {    void style();}public class Order implements Style {    @Override    public void style() {        System.out.println("设置Order");    }}public class Radius implements Style {    @Override    public void style() {        System.out.println("设置Radius");    }} public class Color implements Style {    @Override    public void style() {        System.out.println("设置Color");    }}public class OrderDecorator implements Style {    private Style style;    public OrderDecorator(Style target) {        this.style = target;    }    @Override    public void style() {        style.style();        decorator();    }    private void decorator() {        System.out.println("设置Order");    }}public class RadiusDecorator implements Style {    private Style style;    public RadiusDecorator(Style target) {        this.style = target;    }    @Override    public void style() {        style.style();        decorator();    }    private void decorator() {        System.out.println("设置Radius");    }}public class ColorDecorator implements Style {    private Style style;    public ColorDecorator(Style target) {        this.style = target;    }    @Override    public void style() {        style.style();        decorator();    }    private void decorator() {        System.out.println("设置Color");    }}

定义三个装饰器类:OrderDecorator, RadiusDecorator, ColorDecorator分别实现Style接口,定义decorator方法用(动态拓展的核心方法之一)。调用完``targetstyle方法后调用decorator`方法实现功能的动态拓展。接着,看看客户端如何使用。

代码语言:javascript
复制
public class Client {    public static void main(String[] args) {        Style style = new Order();        Style style1 = new ColorDecorator(style);        Style style2 = new RadiusDecorator(style1);        style2.style();    }}

输出结果:

代码语言:javascript
复制
设置Order设置Color设置Radius

修改版v2

上述优化可以看到一些重复冗余的代码,还有再次优化的空间。以下是实现样例。

代码语言:javascript
复制
public interface Style {    void style();}public class Order implements Style {    @Override    public void style() {        System.out.println("设置Order");    }}public class Radius implements Style {    @Override    public void style() {        System.out.println("设置Radius");    }}public class Color implements Style {    @Override    public void style() {        System.out.println("设置Color");    }}public abstract class StyleDecorator implements Style { // 抽出共通新建装饰类的高层抽象类    protected Style style;    public StyleDecorator(Style target) {        this.style = target;    }    @Override    public void style() { // style设置        style.style();        decorator();    }    protected abstract void decorator(); // 装饰方法}public class OrderDecorator extends StyleDecorator {    public OrderDecorator(Style target) {        super(target);    }    @Override    protected void decorator() {        System.out.println("设置Order");    }}public class RadiusDecorator extends StyleDecorator {    public RadiusDecorator(Style target) {        super(target);    }    @Override    protected void decorator() {        System.out.println("设置Radius");    }}public class ColorDecorator extends StyleDecorator {    public ColorDecorator(Style target) {        super(target);    }    @Override    protected void decorator() {        System.out.println("设置Color");    }}

客户端的使用和输出结果还是和v1一样。

代码语言:javascript
复制
public class Client {    public static void main(String[] args) {        Style style = new Order();        Style style1 = new ColorDecorator(style);        Style style2 = new RadiusDecorator(style1);        style2.style();    }}

输出结果:

代码语言:javascript
复制
设置Order设置Color设置Radius

新建高层抽象类,讲冗余的方法属性都打包到抽象类中,减少重复的代码。 这个应该属于题外话了,可以见得设计模式的实现方式是多种多样的。不要过度拘泥于模板。只要能达成目的,想怎么设计就可以怎么设计。

修改版v1和v2都是装饰器模式,实际开发根据需求斟酌即可。

总结

优点

  1. 开发时可以自由组合各种各样的功能。
  2. 新增的功能对于现有功能没有任何的影响。

缺点

  1. 增加系统的复杂度。
  2. 对于开发人员的技术要求提高。

应用场景

  1. 需要灵活组合功能的场合。
  2. 限制继承,但又想拓展类的功能的场合。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • 优化案例
    • 最初版v0
      • 修改版v1
        • 修改版v2
        • 总结
          • 优点
            • 缺点
              • 应用场景
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档