iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >详解Java如何通过装饰器模式扩展系统功能
  • 149
分享到

详解Java如何通过装饰器模式扩展系统功能

Java装饰器模式应用Java装饰器模式Java装饰模式 2023-05-16 14:05:20 149人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录装饰器模式概述简单案例案例场景装饰器模式优缺点优点缺点装饰器模式适用场景总结尽管目前房价依旧很高,买房的人依旧很多。如果大家买的是毛坯房,无疑还有一项艰巨的任务要面对,那就是装修

尽管目前房价依旧很高,买房的人依旧很多。如果大家买的是毛坯房,无疑还有一项艰巨的任务要面对,那就是装修。对新房进行装修并没有改变房屋用于居住的本质,但它可以让房子变得更漂亮、更温馨、更实用、更能满足居家的需求。在软件设计中,我们也有一种类似新房装修的技术可以对已有对象(新房)的功能进行扩展(装修),以获得更加符合用户需求的对象,使得对象具有更加强大的功能。这种技术对应于一种被称之为装饰模式的设计模式,本章将介绍用于扩展系统功能的装饰模式。

装饰器模式概述

装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为,在现实生活中,这种情况也到处存在,例如一张照片,我们可以不改变照片本身,给它增加一个相框,使得它具有防潮的功能,而且用户可以根据需要给它增加不同类型的相框,甚至可以在一个小相框的外面再套一个大相框。

装饰模式是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系。在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能。

装饰模式结构图:

  • Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。
  • ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
  • Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
  • ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。

由于具体构件类和装饰类都实现了相同的抽象构件接口,因此装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

简单案例

场景:天气太热了,喝点儿冰水解解暑;加点儿柠檬片,让果汁好喝点儿。

先定义一个喝水的接口

public interface Drink {
    
    void drink();
}

写一个接口的实现

public class DrinkWater implements Drink {

    @Override
    public void drink() {
        System.out.println("喝水");
    }

}

一个简单的装饰器

public class DrinkDecorator implements Drink {

    private final Drink drink;

    public DrinkDecorator(Drink drink) {
        this.drink = drink;
    }

    @Override
    public void drink() {
        System.out.println("先加点儿柠檬片");
        drink.drink();
    }

}

测试

public class DrinkMain {
    public static void main(String[] args) {
        Drink drink = new DrinkWater();
        drink = new DrinkDecorator(drink);
        drink.drink();
    }
}

运行结果

先加点儿柠檬片
喝水

一个简单的装饰器模式例子就写完了,这里只是先了解一下装饰器模式。

案例场景

大家应该都喝过奶茶吧,我经常喝的原味奶茶,里面可以添加配料,每增加一种配料,该奶茶的价格就会增加,要求计算一种奶茶的价格。

下面就可以使用装饰器模式来模拟这种场景。

定义抽象构件类


public interface MilkyTea {
    double cost();
}

定义具体构件类


public class PearlMilkyTea implements MilkyTea{
    @Override
    public double cost() {
        return 13.0;
    }
}

定义抽象装饰类

public abstract class MilkyTeaDecorator implements MilkyTea{

    private MilkyTea milkyTea;

    public MilkyTeaDecorator(MilkyTea milkyTea){
        this.milkyTea = milkyTea;
    }

    @Override
    public double cost() {
        return milkyTea.cost();
    }
}

定义具体装饰类


public class CoconutDecorator extends MilkyTeaDecorator{

    public CoconutDecorator(MilkyTea milkyTea) {
        super(milkyTea);
    }

    @Override
    public double cost() {
        System.out.println("添加椰果");
        return super.cost() + 2.0;
    }
}



public class PuddingDecorator extends MilkyTeaDecorator{

    public PuddingDecorator(MilkyTea milkyTea) {
        super(milkyTea);
    }

    @Override
    public double cost() {
        System.out.println("添加布丁");
        return super.cost() + 1.5;
    }
}

测试代码

public class Client {
    public static void main(String[] args) {
        MilkyTea milkyTea = new PearlMilkyTea();
        milkyTea = new CoconutDecorator(milkyTea);
        milkyTea = new PuddingDecorator(milkyTea);
        System.out.println(milkyTea.cost());
    }
}

运行结果

添加布丁
添加椰果
16.5

在客户端代码中,我们先定义了一个MilkyTea类型的具体构件对象milkyTea,然后将milkyTea作为构造函数的参数注入到具体装饰类CoconutDecorator中,得到一个装饰之后对象milkyTea,再将装饰了一次之后的milkyTea对象注入另一个装饰类PuddingDecorator中实现第二次装饰,得到一个经过两次装饰的对象milkyTea,再调用milkyTea的cost()方法即可得到一杯既加了布丁又加了椰果的珍珠奶茶价格。

装饰器模式优缺点

优点

  • 装饰类和被装饰类可以独立发展,不会相互耦合。
  • 相比于继承,更加的轻便、灵活。
  • 可以动态扩展一个实现类的功能,不必修改原本代码

缺点

  • 会产生很多的装饰类,增加了系统的复杂性。
  • 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。

装饰器模式适用场景

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种扩展或者扩展之间的组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类已定义为不能被继承(如Java语言中的final类)。

总结

装饰模式降低了系统的耦合度,可以动态增加或删除对象的职责,并使得需要装饰的具体构件类和具体装饰类可以独立变化,以便增加新的具体构件类和具体装饰类。在软件开发中,装饰模式应用较为广泛,例如在Javaio中的输入流和输出流的设计、javax.swing包中一些图形界面构件功能的增强等地方都运用了装饰模式。

到此这篇关于详解Java如何通过装饰器模式扩展系统功能的文章就介绍到这了,更多相关Java装饰器模式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解Java如何通过装饰器模式扩展系统功能

本文链接: https://www.lsjlt.com/news/209978.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解Java如何通过装饰器模式扩展系统功能
    目录装饰器模式概述简单案例案例场景装饰器模式优缺点优点缺点装饰器模式适用场景总结尽管目前房价依旧很高,买房的人依旧很多。如果大家买的是毛坯房,无疑还有一项艰巨的任务要面对,那就是装修...
    99+
    2023-05-16
    Java装饰器模式应用 Java装饰器模式 Java装饰模式
  • Java怎么通过装饰器模式扩展系统功能
    这篇文章主要介绍“Java怎么通过装饰器模式扩展系统功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java怎么通过装饰器模式扩展系统功能”文章能帮助大家解决问题。装饰器模式概述装饰模式可以在不改...
    99+
    2023-07-06
  • 如何使用策略模式与装饰模式扩展JavaScript表单验证功能
    这篇文章主要介绍了如何使用策略模式与装饰模式扩展JavaScript表单验证功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。简单的表单验证...
    99+
    2022-10-19
  • 详解Java如何优雅的使用装饰器模式
    目录什么是装饰器模式优点缺点使用场景装饰器模式和代理模式的区别装饰器的简单实现装饰器模式实战小结什么是装饰器模式 装饰器模式(Decorator Pattern): 在不改...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作