Java设计模式——装饰者设计模式 1 基本概括 2 主要介绍 3 代码示例

2021-08-14 09:03     浏览: 14 次 来源: 程序员进阶之路

来源地址: https://www.toutiao.com/a6989140178602541571/?channel=&source=search_tab
免责声明: 本栏目资源为转载资源如有侵权请联系 企鹅:826319429 告知本站将及时删除谢谢!


1 基本概括

Java设计模式——装饰者设计模式

2 主要介绍

2.1 概念

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

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。动态地将责任附加到对象上,若要扩展功能,装饰着提供了比继承更有弹性的替代方案

2.2 主要组成

在装饰模式中,一共有四个角色,分别是 抽象主体、具体主体、抽象装饰、具体装饰。

抽象主体:一个接口或抽象类,以规范需要装饰的主体类,比如:手抓饼

具体主体:具体的需要装饰的主体,比如,普通手抓饼

抽象装饰:持有抽象主体的实例,并实现或继承抽象主体。比如:抽象的材料

具体装饰:具体的装饰品,需继承或实现抽象装饰。表示具体的材料如鸡蛋,香肠等

装饰者设计模式的过程

Java设计模式——装饰者设计模式

2.3 应用场景

装饰者在代码程序中适用于以下场景:

1、用于扩展一个类的功能或给一个类添加附加职责。

2、动态的给一个对象添加功能,这些功能可以再动态的撤销。

2.4 优缺点

优点:

  • 装饰者比继承灵活,可以在不改变原有对象的情况下动态地给一个对象扩展功能,即插即用非常方便
  • 通过不同的装饰器组合,可以实现不同效果
  • 装饰者完全遵守开闭原则。

缺点:

  • 会增加程序复杂性,会增加更多的类
  • 动态装饰时,操作多层装饰复杂

2.5 原则

  • 封装变化
  • 多用组合少用继承
  • 针对接口编程,不针对实现编程
  • 为了交互对象之间的松耦合而努力
  • 类应该对扩展开放,对修改关闭

3 代码示例

3.1 实现过程

1. 手抓饼接口

/**
 * 手抓饼接口
 */
public interface Cake {
    public String getCake();
    public double getPrice();
}


2. 基本手抓饼实现

/**
 *  普通手抓饼5元
 */
public class BaseCake implements Cake{
    @Override
    public String getCake() {
        return "手抓饼";
    }
    @Override
    public double getPrice() {
        return 5;
    }
}


3. 加蛋装饰器

/**
 *  加一个鸡蛋需要加2元
 */
public class AddEggCake implements Cake {

    private Cake cake;

    public AddEggCake(Cake cake){
        this.cake = cake;
    }

    @Override
    public String getCake() {
        return cake.getCake() + " + 鸡蛋";
    }

    @Override
    public double getPrice() {
        return cake.getPrice() + 2;
    }
}


4. 加香肠装饰器

/**
 *  加一根肠需要加3元
 */
public class AddSusageCake implements Cake {

    private Cake cake;

    public AddSusageCake(Cake cake){
        this.cake = cake;
    }
    
    @Override
    public String getCake() {
        return cake.getCake() + " + 肠";
    }

    @Override
    public double getPrice() {
        return cake.getPrice() + 3;
    }
}


5. 测试类

 public class Run {
    public static void main(String[] args) {
        //普通手抓饼
        Cake cake1 = new BaseCake();
        System.out.println("手抓饼:" + cake1.getCake() + ",需要支付" + cake1.getPrice() + "元");
        //手抓饼+鸡蛋
        Cake cake2 = new BaseCake();
        cake2 = new AddEggCake(cake2);
        System.out.println("手抓饼+鸡蛋:" + cake2.getCake() + ",需要支付" + cake2.getPrice() + "元");
        //手抓饼+ 2个鸡蛋 + 一根肠
        Cake cake3 = new BaseCake();
        cake3 = new AddEggCake(cake3);
        cake3 = new AddEggCake(cake3);
        cake3 = new AddSusageCake(cake3);
        System.out.println("手抓饼+2个鸡蛋+一根肠:" + cake3.getCake() + ",需要支付" + cake3.getPrice() + "元");
    }
}

一起讨论学习的可以的点下关注,会持续更新,文章有用的话可以收藏转发,有什么补充可以在下面评论,谢谢

服务支持

我们珍惜您每一次在线询盘,有问必答,用专业的态度,贴心的服务。

让您真正感受到我们的与众不同!