设计模式——装饰器模式

这篇具有很好参考价值的文章主要介绍了设计模式——装饰器模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

优缺点

优点

  1. 不改动原有代码,动态增加功能。
  2. 对象间不会相互依赖、松耦合。
  3. 符合开闭原则,扩展性好,便于维护。

缺点

  1. 装饰器环节过多的话,导致装饰器类膨胀。
  2. 装饰器层层嵌套比较复杂,可能导致排查问题流程繁琐。

装饰器模式的结构

通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰器模式的目标。下面来分析其基本结构和实现方法。

模式的结构

装饰器模式主要包含以下角色。

  1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
  3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

装饰器模式的结构图如图所示。

设计模式——装饰器模式,设计模式,设计模式,装饰器模式,数据库

装饰器模式实例:

实例——图画

不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

代码如下:

画(Painting接口)

public interface Painting {
  public void show();
}

唐宫仕女图(TangGong类)

public class TangGong implements Painting {
  @Override
  public void show(){
    System.out.println("这是一副唐宫仕女图");
  }
}

装饰器类

public class Decorator implements Painting {
  private Painting painting;
  public Decorator(Painting monaLisa){
    this.painting = monaLisa;
  }
  @Override
  public void show() {
    System.out.println("先加上相框");
    painting.show();
    System.out.println("再扣上玻璃");
  }
}

测试类

public class DecoratorTest {
  public static void main(String[] args) {
    Painting painting = new TangGong();
    Painting monaLisa = new Decorator(painting);

    TangGong.show();
  }
}
实现方式 ——蜜雪冰城奶茶

秋天到了,女朋友非要喝秋天的第一杯奶茶,到了“蜜雪冰城”奶茶店后,给女朋友点了一杯奶茶,加了珍珠、芒果等配料,给自己点了一杯加冰柠檬水,加了冰块、柠檬片等配料,这时候就可以使用装饰器模式。

奶茶:抽象构件
珍珠芒果奶茶、柠檬水:具体构件
配料:装饰角色
珍珠、芒果、柠檬:具体装饰角色

代码实现:

抽象构件(Component)角色:奶茶

public interface IMilktea {
    void addDosing();
}

具体构件(ConcreteComponent)角色:珍珠奶茶

public class PearlMilktea implements IMilktea{
    @Override
    public void addDosing() {
        System.out.println("开始制作:珍珠奶茶");
    }
}

柠檬水

public class LemonMilktea implements IMilktea{
    @Override
    public void addDosing() {
        System.out.println("开始制作:柠檬水");
    }
}

装饰(Decorator)角色:配料

public abstract  class Dosing implements IMilktea{

    IMilktea iMilktea;

    public Dosing(IMilktea iMilktea){
        this.iMilktea = iMilktea;
    }

    @Override
    public void addDosing() {
        this.iMilktea.addDosing();
    }
}

具体装饰(ConcreteDecorator)角色:

加珍珠

public class Pearl extends Dosing {

    public Pearl(IMilktea iMilktea) {
        super(iMilktea);
    }

    @Override
    public void addDosing() {
        super.addDosing();
        System.out.println("制作中:加珍珠");
    }
}

加芒果

public class Mango extends Dosing {

    public Mango(IMilktea iMilktea) {
        super(iMilktea);
    }

    @Override
    public void addDosing() {
        super.addDosing();
        System.out.println("制作中:加芒果");
    }
}

加柠檬

public class Lemon extends Dosing {
    public Lemon(IMilktea iMilktea) {
        super(iMilktea);
    }

    @Override
    public void addDosing() {
        super.addDosing();
        System.out.println("制作中:加柠檬");
    }
}

加冰

public class Ice extends Dosing {

    public Ice(IMilktea iMilktea) {
        super(iMilktea);
    }

    @Override
    public void addDosing() {
        super.addDosing();
        System.out.println("制作中:加冰");
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        System.out.println("服务员:你好,需要点什么呀?");
        System.out.println("我: 一杯加芒果、加珍珠的珍珠奶茶,一杯加柠檬、加冰的柠檬水");
        System.out.println("服务员:好的。");
        PearlMilktea pearlMilktea = new PearlMilktea();
        Pearl pearl = new Pearl(pearlMilktea);
        Mango mango = new Mango(pearl);
        Ice ice = new Ice(mango);
        ice.addDosing();

        System.out.println("第一杯制作完成");
        LemonMilktea lemonMilktea = new LemonMilktea();
        Lemon lemon = new Lemon(lemonMilktea);
        Ice ice1 = new Ice(lemon);
        ice1.addDosing();
        System.out.println("第二杯制作完成");

        System.out.println("我:珍珠奶茶怎么加冰了?");
        System.out.println("服务员:对不起,珍珠奶茶做错了,重新给您做。");

        mango.addDosing();
        System.out.println("不加冰的珍珠奶茶制作完成");
        System.out.println("我:好的,谢谢!");
    }
}

输出结果

服务员:你好,需要点什么呀?
我: 一杯加芒果、加珍珠的珍珠奶茶,一杯加柠檬、加冰的柠檬水
服务员:好的。
开始制作:珍珠奶茶
制作中:加珍珠
制作中:加芒果
制作中:加冰
第一杯制作完成
开始制作:柠檬水
制作中:加柠檬
制作中:加冰
第二杯制作完成
我:珍珠奶茶怎么加冰了?
服务员:对不起,珍珠奶茶做错了,重新给您做。
开始制作:珍珠奶茶
制作中:加珍珠
制作中:加芒果
不加冰的珍珠奶茶制作完成
我:好的,谢谢!

到此,女朋友喝到了秋天的第一杯奶茶。文章来源地址https://www.toymoban.com/news/detail-684377.html

应用场景

  • 动态的增加对象的功能;
  • 不能以派生子类的方式来扩展功能;
  • 限制对象的执行条件;
  • 参数控制和检查等;

到了这里,关于设计模式——装饰器模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包