Java设计模式之装饰模式详解

Java设计模式之装饰模式详解

简介

装饰模式是一种结构型设计模式,它允许我们在不改变现有对象结构的情况下向其中添加新功能。

在装饰模式中,我们创建一个装饰器(Decorator)类,用于包装原有的类,并在原有基础上添加新的行为、状态或属性。这种方式实现了对原有类的扩展,同时也不影响原有类的行为。

设计原则

  • 开放-封闭原则(Open-Closed Principle):软件中的对象(类、模块、函数等)应该对扩展开放,但对修改封闭。
  • 单一职责原则(Single Responsibility Principle):一个类应该只有一个引起它变化的原因。

示例

示例1:实现一个饮料类

我们首先创建一个饮料类(Beverage)用于表示所有饮料的基类。该类只包含一个描述信息(description)与一个计算饮料价格的方法(cost)。

public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

接下来,我们创建两个具体的饮料类:Espresso(浓缩咖啡)和HouseBlend(混合咖啡)。这两个类分别继承自饮料基类,实现了自己的饮料描述和价格计算方式。

public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }

    public double cost() {
        return 1.99;
    }
}

public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "House Blend Coffee";
    }

    public double cost() {
        return 0.89;
    }
}

现在我们已经实现了两个饮料类,并且可以计算出它们的价格。但是现在,我们需要为这些饮料添加一些调料,比如蒸奶、摩卡等。我们可以借助装饰模式完成这个功能。

示例2:实现饮料调料类

我们首先创建一个调料类(CondimentDecorator),作为装饰器类的基类。该类也继承自饮料基类,实现了自己的饮料描述和价格计算方式。

public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

接下来,我们创建一些具体的调料类:Milk(牛奶)、Mocha(摩卡)和Soy(豆浆)。这些调料类同样继承自调料基类,实现了自己的调料描述和价格计算方式。

public class Milk extends CondimentDecorator {
    Beverage beverage;

    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }

    public double cost() {
        return 0.10 + beverage.cost();
    }
}

public class Mocha extends CondimentDecorator {
    Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    public double cost() {
        return 0.20 + beverage.cost();
    }
}

public class Soy extends CondimentDecorator {
    Beverage beverage;

    public Soy(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Soy";
    }

    public double cost() {
        return 0.15 + beverage.cost();
    }
}

这些调料类与饮料类非常类似,但它们包装了一个被装饰对象(即饮料对象),并重写了getDescription方法和cost方法。在这里,getDescription方法返回饮料对象的描述信息,加上调料对象的描述信息。cost方法返回饮料对象的价格,加上调料对象的价格。

示例3:组合饮料和调料

现在,我们可以组合多个饮料和调料,创建出不同的组合饮料。

Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());

Beverage beverage2 = new HouseBlend();
beverage2 = new Soy(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Milk(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

在第一个例子中,我们创建了一杯浓缩咖啡,它没有任何调料,价格为1.99美元。

在第二个例子中,我们创建了一杯混合咖啡,加上了豆浆、摩卡和牛奶三种调料,价格为1.34美元。

总结

装饰模式是一种优秀的设计模式,在软件开发中有着广泛的应用,它可以帮助我们灵活地扩展类的功能,并且不影响原有类的行为。这个模式有一个清晰的结构,其中基础组件与装饰器组件之间耦合度非常低。我们只需为基础组件和装饰器组件定义相同的接口,并让它们都从同一个基类继承而来,就可以轻松地组合它们。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之装饰模式详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Spring Cloud Config 使用本地配置文件方式

    下面是关于Spring Cloud Config使用本地配置文件的攻略: 什么是Spring Cloud Config? Spring Cloud Config 是一个分布式配置服务,目的是为分布式系统中的基础设施和微服务应用提供一种集中化的外部配置支持。 使用本地配置文件方式 步骤一:创建本地配置文件 在本地文件系统的一个目录下创建一个配置文件,比如:ap…

    Java 2023年5月19日
    00
  • 微信小程序授权登陆及每次检查是否授权实例代码

    下面我将详细讲解微信小程序授权登陆及每次检查是否授权的方法以及提供两条示例说明。 微信小程序授权登陆的方法 在小程序中调用 wx.getSetting 方法获取用户的授权状态。 wx.getSetting({ success: function(res) { if (res.authSetting[‘scope.userInfo’]) { // 用户已授权,…

    Java 2023年5月23日
    00
  • vuejs 动态添加input框的实例讲解

    下面就来详细讲解“vuejs 动态添加input框的实例讲解”的完整攻略。 简介 在网页开发中,有时候需要根据用户需求动态添加表单输入框,这个过程可以用Vue的v-for指令实现。v-for指令用于绑定数组数据,允许我们对数组数据进行循环渲染。下面通过两个示例来详细讲解Vue动态添加input框的实现方法。 示例一:按钮添加input框 该示例演示按下按钮就…

    Java 2023年6月15日
    00
  • JAVA如何获取客户端IP地址和MAC地址

    获取客户端IP地址和MAC地址是Java开发中经常用到的技巧,下面将详细介绍如何实现。 获取客户端IP地址 在Java中获取客户端IP地址需要先获取请求头中的IP地址,然后通过这个IP地址去判断客户端具体的位置。以下是获取IP地址的代码: // 获取HttpServletRequest对象 HttpServletRequest request = (Http…

    Java 2023年5月26日
    00
  • Javac/javap 自带工具简单使用讲解

    Javac和Javap是Java语言中自带的两个工具。Javac能够将Java源代码编译为可执行Java字节代码,而Javap则可以将Java字节码反编译为可读性更高的代码。 使用Javac编译Java源代码 Javac是Java编译器,可将Java源文件编译成字节代码。当然,在使用Javac之前,我们需要先下载并安装Java开发工具包(JDK)。以下是使用…

    Java 2023年5月23日
    00
  • IDEA生成可运行jar包(包含第三方jar包)流程详解

    下面是”IDEA生成可运行jar包(包含第三方jar包)流程详解”的完整攻略: 一、前置条件 在进行下面的步骤之前,必须确保满足以下条件: 安装了Java开发工具包(JDK) 安装了IntelliJ IDEA开发环境 确保本地已经存在可运行程序的代码 二、生成可运行jar包 1. 配置Maven 在IntelliJ IDEA中打开Maven Projects…

    Java 2023年5月19日
    00
  • HttpClient基础解析

    HttpClient基础解析 什么是HttpClient? HttpClient是Apache软件基金会所提供的一个用于处理HTTP请求的第三方库。其提供了方便的API,使得我们可以通过代码实现HTTP请求的发送与响应的接收。 HttpClient的优点 简单易用:HttpClient提供了方便的API,使得我们可以通过简单的代码实现HTTP请求的发送与响应…

    Java 2023年5月20日
    00
  • Java基础之代码死循环详解

    Java基础之代码死循环详解 简介 代码死循环是指在程序运行过程中,因为某些原因造成程序不停地重复执行某一段代码的现象。死循环通常是因为程序设计不合理或者编写错误所导致的,如果长时间不会自动退出,会造成计算机死机或者卡死。代码死循环是编写程序时需要避免的错误。 常见死循环 for循环死循环 for(int i=0; i>=0; i++){ System…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部