java实现装饰器模式(Decorator Pattern)

yizhihongxing

Java实现装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许我们动态地将行为添加到某个对象中,而不是通过继承来实现。它是在保持类方法签名不变的情况下增加功能,实现类的功能扩展。

角色介绍

  • Component:抽象组件,定义装饰者和被装饰者的最基本的接口和规范。
  • ConcreteComponent:具体组件,也是被装饰器装饰的基本对象,实现抽象组件中的方法。
  • Decorator:抽象装饰器,实现了Component接口,并且持有一个被装饰者的引用。旨在为后续的具体装饰器提供代理或者委托相应的行为扩展。
  • ConcreteDecorator:具体装饰器,继承Decorator,重写接口中的方法,完成相应的装饰逻辑。

示例1:文字消息发送功能

我们需要设计一个具有文字消息发送能力的聊天应用,但是仅仅有文字消息发送的聊天,显然这个应用并不太好用。所以,我们需要实现添加表情和图片消息的功能。

我们可以将文字消息发送功能抽象为一个Component类,即AbstractMessageSender类,然后定义三个装饰器:EmoticonMessageSender、PictureMessageSender和RedPacketMessageSender,分别用于装饰Component类,实现添加表情、图片和红包消息的功能。

public abstract class AbstractMessageSender {
    public abstract void sendMessage();
}

public class TextMessageSender extends AbstractMessageSender {
    @Override
    public void sendMessage() {
        System.out.println("发送了一条文字消息");
    }
}

public abstract class MessageSenderDecorator extends AbstractMessageSender {
    protected AbstractMessageSender messageSender;

    public MessageSenderDecorator(AbstractMessageSender messageSender) {
        this.messageSender = messageSender;
    }

    public void sendMessage() {
        messageSender.sendMessage();
    }
}

public class EmoticonMessageSender extends MessageSenderDecorator {
    public EmoticonMessageSender(AbstractMessageSender messageSender) {
        super(messageSender);
    }

    @Override
    public void sendMessage() {
        super.sendMessage();
        System.out.println("带有表情的消息");
    }
}

public class PictureMessageSender extends MessageSenderDecorator {
    public PictureMessageSender(AbstractMessageSender messageSender) {
        super(messageSender);
    }

    @Override
    public void sendMessage() {
        super.sendMessage();
        System.out.println("带有图片的消息");
    }
}

public class RedPacketMessageSender extends MessageSenderDecorator {
    public RedPacketMessageSender(AbstractMessageSender messageSender) {
        super(messageSender);
    }

    @Override
    public void sendMessage() {
        super.sendMessage();
        System.out.println("带有红包的消息");
    }
}

使用示例代码:

AbstractMessageSender textMessageSender = new TextMessageSender();
textMessageSender = new EmoticonMessageSender(textMessageSender);
textMessageSender = new PictureMessageSender(textMessageSender);
textMessageSender = new RedPacketMessageSender(textMessageSender);
textMessageSender.sendMessage();

运行结果为:

发送了一条文字消息
带有表情的消息
带有图片的消息
带有红包的消息

示例2:饮料点单系统

我们现在要实现一个简单的点单系统,基础饮料有红茶、绿茶和奶茶,但是用户可以选择加入椰果、芋头、珍珠等等不同口味的配料。这些配料是新增的,我们不希望因为新的加入而修改原本的代码,更好的方法是采用装饰器模式。

我们定义一个抽象类Beverage,表示基础饮料。具体的基础饮料类RedTea、GreenTea和MilkTea实现Beverage接口,然后配料类可以继承或实现Beverage接口,形成装饰器类Milk、Pearl、Coconut等。

public abstract class Beverage {
    protected String name;

    public String getName() {
        return name;
    }

    public abstract double cost();
}

public class RedTea extends Beverage {
    public RedTea() {
        super.name = "红茶";
    }

    public double cost() {
        return 10;
    }
}

public class GreenTea extends Beverage {
    public GreenTea() {
        super.name = "绿茶";
    }

    public double cost() {
        return 8;
    }
}

public class MilkTea extends Beverage {
    public MilkTea() {
        super.name = "奶茶";
    }

    public double cost() {
        return 12;
    }
}

public abstract class CondimentDecorator extends Beverage {
    protected Beverage beverage;

    public abstract String getName();

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

public class Milk extends CondimentDecorator {
    public Milk(Beverage beverage) {
        super(beverage);
    }

    public String getName() {
        return beverage.getName() + " 加牛奶";
    }

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

public class Pearl extends CondimentDecorator {
    public Pearl(Beverage beverage) {
        super(beverage);
    }

    public String getName() {
        return beverage.getName() + " 加珍珠";
    }

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

public class Coconut extends CondimentDecorator {
    public Coconut(Beverage beverage) {
        super(beverage);
    }

    public String getName() {
        return beverage.getName() + " 加椰果";
    }

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

使用示例代码:

Beverage redTea = new RedTea();
System.out.println(redTea.getName() + ",价格:" + redTea.cost());

Beverage milkWithGreenTea = new Milk(new GreenTea());
System.out.println(milkWithGreenTea.getName() + ",价格:" + milkWithGreenTea.cost());

Beverage pearlWithMilkTea = new Pearl(new MilkTea());
System.out.println(pearlWithMilkTea.getName() + ",价格:" + pearlWithMilkTea.cost());

Beverage coconutWithGreenWithMilkTea = new Coconut(new Milk(new GreenTea()));
System.out.println(coconutWithGreenWithMilkTea.getName() + ",价格:" + coconutWithGreenWithMilkTea.cost());

运行结果为:

红茶,价格:10.0
绿茶 加牛奶,价格:10.5
奶茶 加珍珠 加牛奶,价格:18.5
绿茶 加牛奶 加椰果,价格:13.5

总结

装饰器模式通过组合的方式,动态地实现增加属性和功能,同时也保证了被装饰器装饰的原对象不会被修改,这种方式增强扩展性更好。但是如果装饰器的嵌套层数过深,可能会影响代码阅读的效率。在设计模式的选择上,应根据具体的需求和情况来进行考虑。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java实现装饰器模式(Decorator Pattern) - Python技术站

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

相关文章

  • java异常处理拦截器详情

    Java异常处理拦截器(Exception Handler)是一个对应用程序中的异常做出响应的组件。它可以捕捉并处理应用程序中发生的异常,从而使程序能够从异常中恢复并继续执行。在Java中,Exception Handler是通过异常处理代码块(try-catch)或者异常处理方法(throws)来实现的。 下面我们将具体讲解如何使用Java异常处理拦截器:…

    Java 2023年5月27日
    00
  • java实现猜拳游戏试题

    下面我将详细讲解“java实现猜拳游戏试题”的完整攻略。 1. 确定游戏规则 在开始编写程序之前,需要先确定猜拳游戏的规则。通常猜拳游戏有剪刀、石头和布三种手势,其中剪刀克制布,布克制石头,石头克制剪刀。参与游戏的两个玩家选择其中一种手势,如果两个玩家选择的手势相同,则为平局;否则根据手势的胜负关系判断胜负,并输出胜负结果。 2. 编写程序 2.1. 实现游…

    Java 2023年5月23日
    00
  • Java精品项目瑞吉外卖之登陆的完善与退出功能篇

    Java精品项目瑞吉外卖之登陆的完善与退出功能篇 概述 本教程旨在介绍Java精品项目瑞吉外卖中登陆的完善与退出功能的实现,包括登陆功能的实现,退出功能的实现以及必要的测试。 登陆功能的实现 1. 前端页面设计 登陆页面需要设计一个表单,包含账号和密码两个输入框,以及一个登陆按钮,具体代码如下: <form> <label for=&quo…

    Java 2023年5月24日
    00
  • 详解Java对象转换神器MapStruct库的使用

    下面我来为你详细讲解“详解Java对象转换神器MapStruct库的使用”的完整攻略。 什么是MapStruct库? MapStruct是一个JavaBean映射工具,它可以自动生成JavaBean之间互相转换的映射代码,从而避免手动编写“getter”和“setter”方法。 MapStruct的使用方法 步骤一:添加依赖 首先,我们需要在项目中添加Map…

    Java 2023年5月26日
    00
  • spring security在分布式项目下的配置方法(案例详解)

    下面为大家详细讲解Spring Security在分布式项目下的配置方法。 1、什么是Spring Security Spring Security 是一个基于 Spring 为后台应用程序提供认证和授权的框架,支持常见的认证和授权技术,并且易于扩展。它能够保护 Web 应用程序及其服务,提供认证和授权相关的附加功能,如密码编码、Single Sign On…

    Java 2023年5月20日
    00
  • IDEA搭建SpringBoot离线工程的方法

    IDEA搭建Spring Boot离线工程的方法 在本文中,我们将详细介绍如何使用 IntelliJ IDEA 搭建 Spring Boot 离线工程。我们将介绍离线工程的概念、搭建步骤和提供两个示例。 离线工程概念 离线工程是指在没有网络连接的情况下,使用本地的依赖库和插件来构建和运行 Spring Boot 应用程序。离线工程可以帮助我们在没有网络连接的…

    Java 2023年5月15日
    00
  • Java Fluent Mybatis 项目工程化与常规操作详解流程篇 下

    Java Fluent Mybatis 项目工程化与常规操作详解流程篇 Java Fluent Mybatis 是一个基于 Mybatis 的 fluent 动态 SQL 构建器,可以帮助我们快速生成复杂的 SQL 语句。下面我们将详细讲解 Java Fluent Mybatis 项目工程化与常规操作的流程。 一、创建项目 首先,我们需要创建一个 Maven…

    Java 2023年5月20日
    00
  • 解决idea中Terminal终端无法执行GIT命令+Terminal 中文乱码问题

    解决idea中Terminal终端无法执行GIT命令+Terminal 中文乱码问题的攻略如下: 问题一:解决idea中Terminal终端无法执行GIT命令 问题描述 在IDEA中使用Terminal终端时,执行git命令时出现如下错误提示: -bash: git: command not found 导致无法正常使用git命令。 解决方法 经过排查发现,…

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