文章目录

  • 组合模式
  • Demo

组合模式


组合模式(Composite Pattern)又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

  • 主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
  • 如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
  • 何时使用:
  1. 您想表示对象的部分-整体层次结构(树形结构)。
  2. 您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
  • 使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
优点 缺点
高层模块调用简单,节点自由增加。 叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。


文件夹-文件的树形结构一定不陌生,文件看作叶子结点(单个对象),文件夹看作中间结点(组合对象)。
组合模式使得用户对单个对象和组合对象的访问具有一致性,即让用户以一致的方式处理个别对象以及组合对象。避免在使用过程中区分开来,造成麻烦。

  • Component :组合中的对象声明接口,用于访问和管理Component子部件。
  • Leaf:单个/叶子对象,叶子结点没有子结点。
  • Composite:组合/容器对象,存储子部件和枝节点行为,实现与子部件有关操作,如增加(add)和删除(remove)等,list实现容器,容纳Component对象。

Demo


以双十一的折扣为例,有VIP折扣、活动折扣、满减、店铺优惠券、红包······

图片摘自网络(papi酱),侵删

先来看看一般的写法:

当用户只满足一种折扣方案时,这种方法还能应对。
但精打细算的我们往往是同时满足多种折扣方案,这时就可以用组合模式,把这些单个折扣方案组合容纳起来,然后定义解决折扣冲突策略。实现单个对象和组合对象的统一,让调用者使用时不必在区分。


把组合对象CompositeDiscount定义成抽象类,SingleMinStrategy和MultipleStrategy继承它,表示解决冲突的策略,分别是取最小折扣和取折上折。
一般解决折扣冲突都是折上折,但商家往往更精明,推出互斥券之类的,即取最小折扣。也可以自定义其他折扣冲突策略。

涉及了点工厂模式和策略模式,DiscountFactory就是实例化Order类的属性DiscountStrategy的工厂,各种折扣策略实现同一接口。

(插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

代码:

public interface DiscountStrategy {public double getTotal(double price);
}public class VIPDiscount implements DiscountStrategy {//95折@Overridepublic double getTotal(double price) {return 0.95*price;}
}
public class ActivityDiscount implements DiscountStrategy{//9折@Overridepublic double getTotal(double price) {return 0.9*price;}
}public class StoreDiscount implements DiscountStrategy{//满500超出部分打6折@Overridepublic double getTotal(double price) {return 500+0.6*(price-500);}
}
public abstract class CompositeDiscount implements DiscountStrategy {protected List<DiscountStrategy> strategies =new ArrayList(); //容器public void add(DiscountStrategy discountStrategy){ //添加叶子结点strategies.add(discountStrategy);}@Overridepublic double getTotal(double price) {return price;}
}//多种折扣选最低折扣
public class SingleMinStrategy extends CompositeDiscount {@Overridepublic double getTotal(double price) {double rtn=price;for (DiscountStrategy s: strategies) {rtn=Math.min(rtn,s.getTotal(price));}return rtn;}
}//多种折扣用折上折
public class MultipleStrategy extends CompositeDiscount {@Overridepublic double getTotal(double price) {double rtn = price;for (DiscountStrategy s : strategies) {rtn = s.getTotal(rtn);}return rtn;}
}
public class DiscountFactory {public DiscountStrategy create(String type){ //工厂来创建相应策略//单一折扣策略if("ynn".equals(type))return new VIPDiscount();else if("nyn".equals(type))return new StoreDiscount();else if("nny".equals(type))return new ActivityDiscount();else{  //多种折扣策略CompositeDiscount compositeDiscount;System.out.println("请选择冲突解决方案:1.折上折 2.最低折");Scanner scanner=new Scanner(System.in);int type2=scanner.nextInt();if(type2==1){compositeDiscount=new MultipleStrategy();}else{compositeDiscount=new SingleMinStrategy();}if(type.charAt(1)=='y')compositeDiscount.add(new StoreDiscount());if(type.charAt(0)=='y')compositeDiscount.add(new VIPDiscount());if(type.charAt(2)=='y')compositeDiscount.add(new ActivityDiscount());return compositeDiscount;}}
}
public class Order {public double price;private String type;public DiscountStrategy discountStrategy;public Order(double price) {this.price=price;}public void display(){System.out.println("总价:"+price);System.out.println("是否是VIP?y/n");Scanner scanner=new Scanner(System.in);type=scanner.next();System.out.println("是否超过500?y/n");String tmp;tmp=scanner.next();type+=tmp;System.out.println("是否满足活动价?y/n");tmp=scanner.next();type+=tmp;DiscountFactory discountFactory=new DiscountFactory();double discountPrice=discountFactory.create(type).getTotal(price);System.out.println("优惠:"+(price-discountPrice));System.out.println("应付:"+discountPrice);}
}public class Client {public static void main(String[] args) {Order order=new Order(620);order.display();}
}

运行结果:


这样一来,无论是单一折扣还是多种折扣,客户端使用时都是一个用法,不必区分和操心。

原创不易,请勿转载(本不富裕的访问量雪上加霜 )
博主首页:https://wzlodq.blog.csdn.net/
微信公众号:吾仄lo咚锵
如果文章对你有帮助,记得一键三连❤

设计模式-组合模式(双十一组合折扣你看懂了吗)相关推荐

  1. Java设计模式之组合模式(透明组合模式,安全组合模式)

    一.概述 组合多个对象形成树形结构以表示具有部分-整体关系的层次结构,可以让客户端统一对待单个对象和组合对象. 组合模式关注那些包含叶子构件和容器构件的结构以及它们的组织形式,在叶子构件中不包含成员变 ...

  2. 组合模式——透明组合模式,安全组合模式

    组合模式 概述 叶子节点进行相关的操作. 可以将这颗树理解成一个大的容器,容器里面包含很多的成员对象,这些成员对象即可是容器对象也可以是叶子对象. 但是由于容器对象和叶子对象在功能上面的区别,使得我们 ...

  3. 组合模式详解附有代码案例分析(包含透明组合模式、安全组合模式的代码示例)

    组合模式 一.组合模式的概念和角色 (一).组合模式的概念 (二).组合模式的角色 二.组合模式的应用场景 三.透明组合模式的代码示例 四.安全组合模式的代码示例 五.组合模式的优缺点 (一).优点 ...

  4. js组合模式和寄生组合模式的区别研究

    最近在阅读<js权威指南>的继承这一章,对于组合模式和寄生组合模式的区别有点混淆,在多次重读以及尝试之后,得到一些心得. 组合模式继承 结合了构造函数继承时可以为每个属性重新初始化,构造一 ...

  5. C++使用组合模式,实现组合图形

    实现一系列图形的操作 描述: 使用C++语言编写一系列的类来实现形状相关的操作.要点如下: 设计一个抽象基类形状(Shape).这个抽象基类有周长.面积.形状类型等纯虚函数. 具体形状有三角形(tri ...

  6. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)

    Java设计模式Ⅳ 1.装饰者模式 1.1 装饰者模式概述 1.2 代码理解 2.组合模式 2.1 组合模式概述 2.2 代码理解 3.外观模式 3.1 外观模式概述 3.2 代码理解 4.享元模式 ...

  7. 1、【设计模式】组合模式

    java设计模式之组合模式 [学习难度:★★★☆☆,使用频率:★★★★☆]  树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式 ...

  8. Java 设计模式之组合模式

    一.了解组合模式 1.1 什么是组合模式 组合模式允许你将对象组合成树形结构来表现"整体/部分"层次机构.组合能够使客户以一致的方式处理个别对象以及组合对象. 组合模式让我们能够用 ...

  9. 设计模式系列-组合模式

    今天下班客厅的灯确实亮堂了许多,照照镜子感觉自己一下苍老许多,看来还是灯光暗比较好,看不出来自己的憔悴啊,哈哈,其实还是头发长了,决定出去剪发. 进到美发店,便有热情的服务生招呼,显示洗头,挑选造型师 ...

最新文章

  1. Unreal Engine 4 优化教程
  2. net平台c#语言如何实现支付宝payto接口
  3. SpringBoot笔记——1
  4. 网卡vlan标签_硬核来了,VLAN揭秘!!!
  5. php赋值就变错误了,PHP基础陷阱题(变量赋值)_PHP教程
  6. [转载] IoT设备WiFi配网及现状
  7. 文本转成图片(自动换行、自定义字体),图片抗锯齿优化,图片压缩优化
  8. 互联网下载.deb安装包
  9. amd linux显卡驱动,AMDAMD ATI Radeon Mobility FireGL 9.10显卡驱动官方正式版下载,适用于linux-驱动精灵...
  10. 人工神经网络评价法案例_人工神经网络评价法
  11. 任正非宣布华为成立“煤炭军团”,进军煤矿业
  12. python升序和降序排序_sql升序和降序(orderby升序和降序排列显示)
  13. 揭秘虚拟化环境高可靠存储的构架和配置
  14. Android M 差分包的制作流程
  15. Android开发如何调用百度翻译api
  16. 多光谱影像分类(双通道CNN实现)
  17. 发运确认后,订单行保持“已挑库”状态 Order Line Remains in Picked (Awaiting Shipping) Status After Ship Confirmation
  18. android 获取图片的真实地址
  19. Android5.0 静音模式下让闹钟仍然响铃
  20. IOS端向下滑动骤停

热门文章

  1. GD32450Z U盘通信教程——使用USBHS利用内部全速PHY作为USB MSC主机实现U盘通信
  2. 《数据结构(信息管理)》
  3. 华为第三方Linux系统好吗,华为linux系统好用吗
  4. 微信FileStorage MsgAttach文件太乱怎么办?教你用Python解决
  5. 计算各种图形的周长 python java
  6. 计算机中单元格地址如何命名,单元格命名_怎样给单元格重新命名或是删除单元格名称_vba...
  7. Android屏幕适配-修改全局density
  8. 水印置顶css,css怎么给网页添加水印效果?
  9. linux下全盘查找文件,linux下的查找文件命令find
  10. 查看geth keystore私钥