Java装饰者模式的示例详解

作者:温故知新之java 时间:2022-03-30 07:26:22 

定义

装饰者模式:在不改变原有对象的基础之上,动态的将功能附加到对象上,提供了继承更有弹性的替代方案,也体现了开闭原则

案例

需求

一个人去咖啡店点了一杯卡布奇诺,加了一份热牛奶

方案

定义咖啡基类

public abstract class Coffee {
   private String desc;

private float price;

public abstract float cost();

public String getDesc() {
       return desc;
   }

public void setDesc(String desc) {
       this.desc = desc;
   }

public float getPrice() {
       return price;
   }

public void setPrice(float price) {
       this.price = price;
   }
}

定义卡布奇诺咖啡类,继承咖啡基类

public class Cappuccino extends Coffee{
   public Cappuccino(){
       setDesc("点了一杯卡布奇诺");
       setPrice(100);
   }

@Override
   public float cost() {
       System.out.println("当前价格为:" + super.getPrice());
       return super.getPrice();
   }
}

定义装饰者类

public class Decorator extends Coffee{

private Coffee coffee;

public Decorator(Coffee coffee){
       this.coffee = coffee;
   }

@Override
   public float cost() {
       return super.getPrice() + this.coffee.cost();
   }

@Override
   public String getDesc() {
       return super.getDesc() + coffee.cost();
   }
}

定义热牛奶类

public class HotMilk extends Decorator {
   public HotMilk(Coffee coffee){
       super(coffee);
       setPrice(200);
       setDesc("点了一杯热牛奶");
   }
}

定义测试类

public class Test {
   public static void main(String[] args) {
       // 点了一杯卡布奇诺,还加了一份热牛奶
       Coffee coffee = new Cappuccino();
       System.out.println(coffee.getDesc());
       //System.out.println(coffee.getPrice());
       System.out.println(coffee.cost());;

HotMilk hotMilk = new HotMilk(coffee);
       System.out.println(hotMilk.getDesc());
       //System.out.println(hotMilk.getPrice());
       System.out.println(hotMilk.cost());
   }
}

查看测试结果

Java装饰者模式的示例详解

分析

装饰者模式的目的也是为了扩展对象的功能,是继承的一个替代模式,可以动态的扩展一个实现类的功能,装饰类和被装饰类可以相互独立,不会耦合,灵活方便。

使用场景

  • 需要给一个现有类添加职责,但是有不能采用生成子类的方式去扩充的时候,

  • 当需要对于现有的一组基本功能进行组合,会产生非常多的功能的时候

  • 当对象的功能要求可以动态的添加,或者说的动态的撤销

知识点补充

装饰模式的定义和特点

在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。

就像我们做菜,需要用到调料,菜,刀,火等一系列抽象的组件来最终完成一道菜。

装饰模式的定义:

指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。就增加功能来说,装饰模式比生成子类更加灵活。

特点:

  • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用

  • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果

  • 装饰器模式完全遵守开闭原则

缺点

装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

装饰模式的结构

装饰模式的结构一般包含以下几个角色

1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。

3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

来源:https://juejin.cn/post/7068553669196644389

标签:Java,设计模式,装饰者模式
0
投稿

猜你喜欢

  • OnSharedPreferenceChangeListener详解及出现不触发解决办法

    2021-10-25 19:06:36
  • 在Java中判断两个Long对象是否相等

    2022-09-01 11:22:10
  • 实现Java删除一个集合的多个元素

    2021-09-19 10:41:28
  • 解析Java中PriorityQueue优先级队列结构的源码及用法

    2023-11-08 13:33:11
  • Spring Security和Shiro的相同点与不同点整理

    2023-01-15 17:07:20
  • Java多线程回调方法实例解析

    2023-11-04 01:40:01
  • SpringBoot中使用Redis Stream实现消息监听示例

    2021-09-02 04:42:07
  • C#实现多线程的Web代理服务器实例

    2022-02-25 13:32:08
  • Java全面深入探究SpringBoot拦截器与文件上传

    2021-11-12 20:08:24
  • RecyclerView实现纵向和横向滚动

    2023-04-03 14:50:44
  • 分享C#中几个可用的类

    2023-08-10 10:47:17
  • Android基于opencv实现多通道分离与合并

    2022-05-04 09:49:29
  • Android列表控件Spinner简单用法示例

    2023-03-06 07:36:22
  • 使用IDEA异常断点来定位java.lang.ArrayStoreException的问题

    2022-06-14 00:43:18
  • Android Rxjava3 使用场景详解

    2023-08-06 08:58:50
  • java使用正则抓取网页邮箱

    2022-12-02 10:30:30
  • HorizontalScrollView水平滚动控件使用方法详解

    2023-02-19 21:12:27
  • java的Console类的使用方法及实例

    2022-09-20 15:47:27
  • 详解Android中的ActivityThread和APP启动过程

    2021-08-20 22:51:25
  • unity实现文字滚动效果

    2021-08-02 17:29:15
  • asp之家 软件编程 m.aspxhome.com