Java设计模式之结构型-装饰器模式(UML类图+案例分析)

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

目录

一、基本概念

二、UML类图

三、角色设计

四、代码实现

案例一

案例二 

五、总结 


一、基本概念

装饰器模式是指不必在改变原有的类和不使用继承的情况下,动态扩展一个对象的功能。

二、UML类图

Java设计模式之结构型-装饰器模式(UML类图+案例分析)

三、角色设计

角色 描述
抽象构件 是一个接口或者抽象类,定义我们最核心的对象
具体构件 抽象构件的实现,可以单独用,也可以将其进行装饰
装饰角色 一般是一个抽象类,继承自或实现抽象构件,在它的属性中有个变量指向抽象构建,这是关键
具体装饰角色 具体的装饰类,可以把基础构件进行装饰,延伸出新的功能

四、代码实现

案例一

假设一个场景,以前手机充电只有usb充电,但是目前手机多出了2种新的充电方式,Typc-C和无线充电,这就需要我们动态去扩展功能,让我们看看装饰器如何实现的。

首先定义一个基本的充电接口,采用usb充电:

public interface Charge {
    
    public void usb();
    
}

实现一个普通手机去使用usb接口充电:

public class PhoneCharge implements Charge{

    @Override
    public void usb() {
        System.out.println("采用usb接口充电...");
    }
    
}

抽象的充电装饰器:

public abstract class AbstractPhoneDecorator implements Charge{

    protected final Charge charge;

    public AbstractPhoneDecorator(Charge charge){
        this.charge = charge;
    }

}

Type-C充电具体装饰:

public class TypeCDecorator extends AbstractPhoneDecorator{


    public TypeCDecorator(Charge charge) {
        super(charge);
    }

    @Override
    public void usb() {
        super.charge.usb();
        System.out.println("采用type-c接口充电...");
    }

}

无线充电的具体装饰:

public class WirelessDecorator extends AbstractPhoneDecorator{

    public WirelessDecorator(Charge charge) {
        super(charge);
    }

    @Override
    public void usb() {
        super.charge.usb();
        System.out.println("采用无线充电...");
    }
    
}

客户端:

public class Client {

    public static void main(String[] args) {
        
        Charge charge = new PhoneCharge();
        TypeCDecorator typeCDecorator = new TypeCDecorator(charge);
        WirelessDecorator wirelessDecorator = new WirelessDecorator(typeCDecorator);
        wirelessDecorator.usb();
        
    }

}

运行结果如下:

Java设计模式之结构型-装饰器模式(UML类图+案例分析)

案例二 

现在假设有一个新的场景,在我们平时网上购买一个商品可以不光使用红包抵扣,同时也有满减优惠,案例二假设一个用户在网上买了10个单价为15元的牙杯,他现在有一个20元的红包和50元的抵扣券,下面通过代码来进行简单的模拟实现。

创建订单实体类:

import java.math.BigDecimal;

/**
 * 订单类
 * @author HTT
 */
public class Order {

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getGoodsInfo() {
        return goodsInfo;
    }

    public void setGoodsInfo(String goodsInfo) {
        this.goodsInfo = goodsInfo;
    }

    public BigDecimal getGoodsPrice() {
        return goodsPrice;
    }

    public void setGoodsPrice(BigDecimal goodsPrice) {
        this.goodsPrice = goodsPrice;
    }

    public BigDecimal getGoodsCount() {
        return goodsCount;
    }

    public void setGoodsCount(BigDecimal goodsCount) {
        this.goodsCount = goodsCount;
    }

    public Coupon getFullReduction() {
        return fullReduction;
    }

    public void setFullReduction(Coupon couponInfo) {
        this.fullReduction = couponInfo;
    }

    public Coupon getRedPacketInfo() {
        return redPacketInfo;
    }

    public void setRedPacketInfo(Coupon redPacketInfo) {
        this.redPacketInfo = redPacketInfo;
    }

    public BigDecimal getGoodsAmount() {
        return goodsAmount;
    }

    public void setGoodsAmount(BigDecimal goodsAmount) {
        this.goodsAmount = goodsAmount;
    }

    /**
     * 订单id
     */
    private String id;

    /**
     * 商品信息
     */
    private String goodsInfo;

    /**
     * 商品价格
     */
    private BigDecimal goodsPrice;

    /**
     * 商品信息
     */
    private BigDecimal goodsCount;

    /**
     * 商品总价
     */
    private BigDecimal goodsAmount;

    /**
     * 满减信息
     */
    private Coupon fullReduction;
    /**
     * 红包信息
     */
    private Coupon redPacketInfo;
}

创建优惠券实体类:

import java.math.BigDecimal;

/**
 * 优惠信息
 * @author HTT
 */
public class Coupon {

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public BigDecimal getCouponPrice() {
        return couponPrice;
    }

    public void setCouponPrice(BigDecimal couponPrice) {
        this.couponPrice = couponPrice;
    }


    public String getCouponType() {
        return couponType;
    }

    public void setCouponType(String couponType) {
        this.couponType = couponType;
    }

    private int id;

    /**
     * 优惠金额
     */
    private BigDecimal couponPrice;

    /**
     * 优惠券类型
     */
    private String couponType;

}

 创建一个抽象构建,是所有订单的基本需求,用于计算订单的总额:

/**
 * 抽象构建 用于计算订单总金额
 * @author HTT
 */
public interface OrderDecorator {

    public BigDecimal calculateOrderPrice(Order order);
    
}

抽象构建的基础实现类:

/**
 * 基础构建实现类 计算订单金额
 * @author HTT
 */
public class BaseOrder implements OrderDecorator{

    @Override
    public BigDecimal calculateOrderPrice(Order order) {
        return order.getGoodsPrice().multiply(order.getGoodsCount());
    }

}

订单的抽象装饰器:

/**
 * 抽象的订单装饰器
 * @author HTT
 */
public abstract class BaseOrderDecorator implements OrderDecorator{

    private OrderDecorator orderDecorator;

    public BaseOrderDecorator(OrderDecorator orderDecorator){
        this.orderDecorator = orderDecorator;
    }

    @Override
    public BigDecimal calculateOrderPrice(Order order) {
        return orderDecorator.calculateOrderPrice(order);
    }

}

红包装饰器:

/**
 * 红包装饰器
 * @author HTT
 */
public class RedPacketDecorator extends BaseOrderDecorator{

    public RedPacketDecorator(OrderDecorator orderDecorator) {
        super(orderDecorator);
    }

    @Override
    public BigDecimal calculateOrderPrice(Order order) {
        order.setGoodsAmount(super.calculateOrderPrice(order));
        return calculateRedPacketPrice(order);
    }

    private BigDecimal calculateRedPacketPrice(Order order){
        return order.getGoodsAmount().subtract(order.getRedPacketInfo().getCouponPrice());
    }
}

满减装饰器:

/**
 * 满减装饰器
 * @author HTT
 */
public class FullReductionDecorator extends BaseOrderDecorator{

    public FullReductionDecorator(OrderDecorator orderDecorator) {
        super(orderDecorator);
    }

    @Override
    public BigDecimal calculateOrderPrice(Order order) {
        order.setGoodsAmount(super.calculateOrderPrice(order));
        return calculateRedPacketPrice(order);
    }

    private BigDecimal calculateRedPacketPrice(Order order){
        return order.getGoodsAmount().subtract(order.getFullReduction().getCouponPrice());
    }
}

客户端:

public class Client {

    public static void main(String[] args) {
        //初始化红包信息
        Coupon redPacket = new Coupon();
        redPacket.setId(1);
        redPacket.setCouponType("红包");
        redPacket.setCouponPrice(new BigDecimal("20"));
        //初始化满减信息
        Coupon fullReduction = new Coupon();
        fullReduction.setId(2);
        fullReduction.setCouponType("满减");
        fullReduction.setCouponPrice(new BigDecimal("50"));

        //初始化订单信息
        Order order = new Order();
        order.setId(UUID.randomUUID().toString());
        order.setGoodsInfo("牙杯");
        order.setGoodsPrice(new BigDecimal("15"));
        order.setGoodsCount(new BigDecimal("10"));
        order.setRedPacketInfo(redPacket);
        order.setFullReduction(fullReduction);

        OrderDecorator orderDecorator = new BaseOrder();
        BaseOrderDecorator redPacketDecorator = new RedPacketDecorator(orderDecorator);
        BaseOrderDecorator fullReductionDecorator = new FullReductionDecorator(redPacketDecorator);
        System.out.println(fullReductionDecorator.calculateOrderPrice(order));

    }


}

运行结果如下:

Java设计模式之结构型-装饰器模式(UML类图+案例分析)

五、总结 

优点:

1、扩展开闭原则。可以通过装饰类扩展功能,而无需修改原类。

2、装饰类和原类接口一致。对使用者透明,易于使用。

3、具体构件类和装饰类可以独立变化,用户可根据需要增加装饰类链。

4、使用组合方式代替继承,更加灵活。

缺点:

1、装饰链过多时,调试和阅读代码困难。

2、不符合单一职责原则,容易出现多装饰器堆叠的情况。

应用场景:

1、扩展类功能场景,特别不希望通过子类继承的方式扩展。

2、动态给对象增加功能,且可按需挑选需要的功能。

3、需要通过对多个类的组合展现功能,而非继承。装饰器模式利用封装和组合的方式灵活地扩展对象功能,遵循开闭原则,而不破坏继承关系。适用于功能扩展的场景中。

符合的设计原则:

1、单一职责原则(Single Responsibility Principle)

装饰类只负责为对象新增功能,而不修改其本身功能。

2、开闭原则(Open Closed Principle)

可以新增装饰类而不需要修改源代码,扩展开放。

3、里氏替换原则(Liskov Substitution Principle)

装饰对象可以替换被装饰对象使用,不影响其他对象。

4、依赖倒转原则(Dependency Inversion Principle)

装饰类和被装饰类都依赖于抽象组件接口,不存在具体依赖。

5、接口隔离原则(Interface Segregation Principle)

组件接口职责单一,不需要强制实现不必要的方法。

装饰器模式通过对象组合方式动态增强功能,遵循开闭原则,在不修改源代码的前提下扩展对象功能,是继承的一个有力补充。文章来源地址https://www.toymoban.com/news/detail-512095.html

到了这里,关于Java设计模式之结构型-装饰器模式(UML类图+案例分析)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【C++设计模式之装饰模式:结构型】分析及示例

    装饰模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地给一个对象添加额外的行为。 描述 装饰模式通过创建一个包装器(Wrapper)来包裹原始对象,并在原始对象的行为前后添加额外的功能。通过这种方式,可以实现在不改变原始对象结构的情况下,动态

    2024年02月07日
    浏览(38)
  • 《golang设计模式》第二部分·结构型模式-04-装饰器模式(Decorator)

    装饰器(Decorator)通过包装(不是继承)的方式向目标对象中动态地添加或删除功能。 Component(抽象组件):定义了原始对象的接口,装饰器也会实现这个接口。 Concrete Component(具体组件):原始对象,以后装饰器会装饰它。 Decorator(抽象装饰器):关联/聚合了抽象组件,

    2024年02月09日
    浏览(51)
  • 设计模式-04.01-结构型-代理&桥接&装饰器&适配器

    创建型模式比较好理解,后面的结构型和行为型设计模式不是那么好理解。如果遇到不好理解的设计模式,我一般会在开头举比较简单的Demo案例来帮助理解。 前面几节,我们讲了设计模式中的创建型模式。创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对

    2024年02月09日
    浏览(60)
  • 【Java 设计模式】结构型之代理模式

    代理模式(Proxy Pattern)是一种结构型设计模式, 它允许通过一个代理对象控制对其他对象的访问 。代理模式在访问对象时引入了一定程度的间接性,使得可以在访问对象前后进行一些额外的操作。在本文中,我们将深入研究Java中代理模式的定义、结构、使用场景以及如何在

    2024年01月21日
    浏览(49)
  • Java学习——设计模式——结构型模式2

    结构型模式主要涉及如何组合各种对象以便获得更好、更灵活的结构。虽然面向对象的继承机制提供了最基本的子类扩展父类的功能,但结构型模式不仅仅简单地使用继承,而更多地通过组合与运行期的动态组合来实现更灵活的功能。 包括: 1、适配器 2、桥接 3、组合 4、装

    2024年02月03日
    浏览(46)
  • 【Java 设计模式】结构型之桥接模式

    桥接模式(Bridge Pattern)是一种结构型设计模式, 它将抽象部分与实现部分分离,使它们可以独立变化,从而降低它们之间的耦合 。桥接模式通过将抽象部分和实现部分分离,使得它们可以独立地变化,同时在它们之间建立一个桥梁。在本文中,我们将介绍 Java 中桥接模式的

    2024年01月19日
    浏览(46)
  • 【Java 设计模式】结构型之外观模式

    外观模式(Facade Pattern)是一种结构型设计模式, 它为复杂系统提供了一个简化的接口,隐藏了系统的复杂性,使得客户端更容易使用系统 。外观模式通过创建一个包装类(外观类),将系统的复杂性封装起来,对客户端提供一个简单的接口。在本文中,我们将深入研究Ja

    2024年01月21日
    浏览(45)
  • 【十】设计模式~~~结构型模式~~~享元模式(Java)

    【学习难度:★★★★☆,使用频率:★☆☆☆☆】         面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。 享元模式正是为解决这一类问题

    2024年02月08日
    浏览(50)
  • Java设计模式-结构型-适配器模式

    ​ 与电源适配器相似,在适配器模式中引入了一个被称为适配器(Adapter)的包装类,而它所包装的对象称为适配者(Adaptee),即被适配的类。适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用

    2024年02月20日
    浏览(57)
  • Java23种设计模式-结构型模式之组合模式

    组合模式 (Composite Pattern):将 对象组合成树状结构 以表示“ 部分-整体 ”层次结构,同时保持对单个对象和组合对象的一致性操作,主要目的是简化客户端代码,因为它可以统一处理单个对象和组合对象。 通常包含以下几个角色: 角色1. 抽象组件 (Component):声明了 组

    2024年04月26日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包