服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - java设计模式-组合模式详解

java设计模式-组合模式详解

2021-10-16 13:31吾仄lo咚锵 Java教程

这篇文章主要介绍了JAVA设计模式之组合模式,简单说明了组合模式的原理,并结合实例分析了java组合模式的具体用法,需要的朋友可以参考下

组合模式

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

  • 主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
  • 如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
  • 何时使用:

1.您想表示对象的部分-整体层次结构(树形结构)。

2.您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

  • 使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
优点 缺点
高层模块调用简单,节点自由增加。 叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

java设计模式-组合模式详解

文件夹-文件的树形结构一定不陌生,文件看作叶子结点(单个对象),文件夹看作中间结点(组合对象)。

组合模式使得用户对单个对象和组合对象的访问具有一致性,即让用户以一致的方式处理个别对象以及组合对象。避免在使用过程中区分开来,造成麻烦。

java设计模式-组合模式详解

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

 

Demo

先来看看一般的写法:

java设计模式-组合模式详解

当用户只满足一种折扣方案时,这种方法还能应对。

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

java设计模式-组合模式详解

把组合对象CompositeDiscount定义成抽象类,SingleMinStrategy和MultipleStrategy继承它,表示解决冲突的策略,分别是取最小折扣和取折上折。

一般解决折扣冲突都是折上折,但商家往往更精明,推出互斥券之类的,即取最小折扣。也可以自定义其他折扣冲突策略。

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

 

代码:

public interface DiscountStrategy {
    public double getTotal(double price);
}
public class VIPDiscount implements DiscountStrategy {
    //95折
    @Override
    public double getTotal(double price) {
        return 0.95*price;
    }
}
public class ActivityDiscount implements DiscountStrategy{
    //9折
    @Override
    public double getTotal(double price) {
        return 0.9*price;
    }
}
public class StoreDiscount implements DiscountStrategy{
    //满500超出部分打6折
    @Override
    public 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);
    }
    @Override
    public double getTotal(double price) {
        return price;
    }
}
//多种折扣选最低折扣
public class SingleMinStrategy extends CompositeDiscount {
    @Override
    public 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 {
    @Override
    public 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();
    }
}

运行结果:

java设计模式-组合模式详解

java设计模式-组合模式详解

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

 

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注服务器之家的更多内容!

原文链接:https://wzlodq.blog.csdn.net/article/details/111251679

延伸 · 阅读

精彩推荐
  • Java教程java解析xml之sax解析xml示例分享

    java解析xml之sax解析xml示例分享

    SAX基于事件的解析,解析器在一次读取XML文件中根据读取的数据产生相应的事件,由应用程序实现相应的事件处理逻辑,即它是一种“推”的解析方式;这...

    java技术网2382019-10-27
  • Java教程利用POI读取word、Excel文件的最佳实践教程

    利用POI读取word、Excel文件的最佳实践教程

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。 下面这篇文章主要给大家介绍了关于利...

    neal8452021-02-22
  • Java教程Java API学习教程之正则表达式详解

    Java API学习教程之正则表达式详解

    正则表达式的强大众所周知,它令程序员的头痛程度也数一数二的。下面这篇文章主要给大家介绍了关于Java API学习教程之正则表达式的相关资料,文中通...

    Single_YAM2332020-12-02
  • Java教程实例分析Java单线程与多线程

    实例分析Java单线程与多线程

    本篇文章通过代码实例给大家详细讲述了Java单线程与多线程的相关原理和知识点总结,需要的朋友可以学习下。...

    彬菌9842021-04-08
  • Java教程登陆验证码kaptcha结合spring boot的用法详解

    登陆验证码kaptcha结合spring boot的用法详解

    在一个web应用中验证码是一个常见的元素。不管是防止机器人还是爬虫都有一定的作用,下面这篇文章主要给大家介绍了登陆验证码kaptcha结合spring boot用法...

    Waiting1822020-11-12
  • Java教程spring boot 部署为jar包的方法示例

    spring boot 部署为jar包的方法示例

    本篇文章主要介绍了spring boot 部署为jar的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Ryan.Miao11902021-01-25
  • Java教程关于java开发的性能问题总结(必看)

    关于java开发的性能问题总结(必看)

    下面小编就为大家带来一篇关于java开发的性能问题总结(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Java之家1372020-08-24
  • Java教程springboot打包部署到linux服务器的方法

    springboot打包部署到linux服务器的方法

    这篇文章主要介绍了springboot打包部署到linux服务器的方法,通过实例代码相结合的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参...

    WoddenFish8722021-05-09