设计模式-组合模式

上文(设计模式-过滤器模式):https://blog.csdn.net/qq_16498553/article/details/106532693


背景

世界分为7大洲,每个国家,一般只属一个洲(像俄罗斯这种除外哈),这样的话就构建成级联关系,一般世界上任何某处地区都所属某个国家,而这个国家又所属某个洲,组合模式是就是将地区(基本对象)和组合对象(国家、洲)不断的去组合成更复杂的的对象。将所有的地区组成树型结构;

组合模式是什么?

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

组合模式的安全性:从客户使用组合模式上看是否更安全。如果是安全的,那么就不会有发生误操作的可能,能访问的方法都是被支持的功能。

组合模式的透明性:从客户使用组合模式上看是否需要区分到底是组合对象还是叶子对象。如果是透明的,那就不用再区分,对于客户而言,都是组件对象,具体的类型对于客户而言是透明的,是客户无须关心的。

包含的角色有:

抽象组件:(Component)角色:这是一个抽象角色,它给参加组合的对象规定一个接口。这个角色给出共有的接口及其默认行为。

叶子对象:(Leaf)角色:代表参加组合的树叶对象。一个树叶没有下级的子对象。定义出参加组合的原始对象的行为。

容器对象:(Composite)角色:代表参加组合的有子对象的对象,并给出树枝构件对象行为。

组合模式可以干嘛?

该模式主要是解决树型结构遍历和递归处理的问题;

优点:

易拓展:节点可以自由增加,遵循了开闭原则;

统一了组合对象和叶子对象,子节点和父节点统一类型;

缺点:

破坏了单一职责,又获取父节点又打印子结点破坏了单一职责;

组合模式类图

 

 

实现代码

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

  • 安全模式

/**
 * @Auther: csh
 * @Date: 2020/5/25 18:08
 * @Description:抽象的位置(抽象构件)
 */
public interface IPosition {
    /**
     *
     * 功能描述:输出位置名称
     *
     * @param: 
     * @return: 
     * @auther: csh
     * @date: 2020/5/25 18:09
     */
    void printPositionName(String preStr);
}
/**
 * @Auther: csh
 * @Date: 2020/5/25 18:13
 * @Description:洲
 */
public class Continent implements IPosition {
    /**
     *
     * 功能描述:各地方
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/25 18:14
     */
    private List<IPosition>  childPosition = new ArrayList <IPosition>();
    /**
     *
     * 功能描述:地方名称
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/25 18:14
     */
    private String name;

    public Continent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    /**
     *
     * 功能描述:添加
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/25 18:16
     */
    public void addChild(IPosition child){
        childPosition.add(child);
    }
    /**
     *
     * 功能描述:删除
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/25 18:16
     */
    public void removeChild(IPosition position){
        childPosition.remove(position);
    }
    /**
     *
     * 功能描述:返回列表
     *
     * @param: 
     * @return: 
     * @auther: csh
     * @date: 2020/5/25 18:16
     */
    public List<IPosition> getChild(){
        return childPosition;
    }



    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void printPositionName(String preStr) {
        //当前的位置
        System.out.println(preStr+"+"+this.name);
        //获取包含的地区
        if(null!=childPosition && childPosition.size()>0){
            preStr+=" ";
            for (IPosition iPosition : childPosition) {
                iPosition.printPositionName(preStr);
            }
        }
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/25 18:33
 * @Description:国家
 */
public class Country implements IPosition {

    /**
     *
     * 功能描述:地方名称
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/25 18:14
     */
    private String name;

    public Country(String name) {
        this.name = name;
    }

    @Override
    public void printPositionName(String preStr) {
        System.out.println(preStr + "-" + name);
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/25 18:36
 * @Description:演示  (安全模式)
 */
public class Client {
    public static void main(String[] args) {
        Continent earth = new Continent("地球");
        Continent asian = new Continent("亚洲");
        Continent america = new Continent("美洲");
        Continent africa = new Continent("非洲");


        Country china = new Country("中国");
        asian.addChild(china);
        Country american = new Country("美国");
        america.addChild(american);
        Country cameroon = new Country("喀麦隆");
        africa.addChild(cameroon);

        earth.addChild(asian);
        earth.addChild(america);
        earth.addChild(africa);

        earth.printPositionName("");
        
    }
}

结果

+地球
 +亚洲
  -中国
 +美洲
  -美国
 +非洲
  -喀麦隆
  • 透明模式

/**
 * @Auther: csh
 * @Date: 2020/5/25 18:13
 * @Description:抽象的地方(组件)
 */
public abstract class IPosition  {

    /**
     *
     * 功能描述:打印位置名称
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/25 18:58
     */
    public abstract void printPositionName(String preStr);
    /**
     *
     * 功能描述: 添加子类
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/26 9:38
     */
    public  void addChild(IPosition child){
        throw  new UnsupportedOperationException("对象不支持此功能");
    }
    /**
     *
     * 功能描述:删除子类
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/26 9:38
     */
    public  void removeChild(IPosition child){
        throw  new UnsupportedOperationException("对象不支持此功能");
    }
    /**
     *
     * 功能描述:获取所有子类
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/5/26 9:40
     */
    public List<IPosition> getChild(){
        throw  new UnsupportedOperationException("对象不支持此功能");
    }


}

 

/**
 * @Auther: csh
 * @Date: 2020/5/26 09:41
 * @Description:洲
 */
public class Continent extends IPosition {

    /**
     *
     * 功能描述:子类集合
     *
     * @param: 
     * @return: 
     * @auther: csh
     * @date: 2020/5/26 9:42
     */
    private List<IPosition> childList = new ArrayList <IPosition>();

    /**
     *
     * 功能描述:对象名称
     *
     * @param: 
     * @return: 
     * @auther: csh
     * @date: 2020/5/26 9:42
     */
    private String name;

    @Override
    public void printPositionName(String preStr) {
        //当前的位置
        System.out.println(preStr+"+"+this.name);
        //获取包含的地区
        if(null!=childList && childList.size()>0){
            preStr+=" ";
            for (IPosition iPosition : childList) {
                iPosition.printPositionName(preStr);
            }
        }
    }


    public Continent(String name) {
        this.name = name;
    }

    @Override
    public void removeChild(IPosition child) {
        childList.remove(child);
    }

    @Override
    public void addChild(IPosition child){
        childList.add(child);
    }

    @Override
    public List <IPosition> getChild() {
        return childList;
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/26 10:23
 * @Description:国家
 */
public class Country extends IPosition{

    private String name;

    public Country(String name) {
        this.name = name;
    }
    
    @Override
    public void printPositionName(String preStr) {
        System.out.println(preStr+"-"+name);
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/26 10:25
 * @Description:透明模式
 */
public class Client {

    public static void main(String[] args) {
        Continent earth = new Continent("地球");
        Continent america = new Continent("美洲");
        Continent asian = new Continent("亚洲");
        Continent africa = new Continent("非洲");

        Country china = new Country("中国");
        asian.addChild(china);
        Country american = new Country("美国");
        america.addChild(american);
        Country cameroon = new Country("喀麦隆");
        africa.addChild(cameroon);

        earth.addChild(asian);
        earth.addChild(america);
        earth.addChild(africa);

        earth.printPositionName("");

    }
}

结果

+地球
 +亚洲
  -中国
 +美洲
  -美国
 +非洲
  -喀麦隆

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

最后

实际使用过程中,透明模式使用得比较多,但是建议在使用该模式的时候加上缓存 redis或者本地缓存,这样高效率更高,没必要每次都去遍历,这样太浪费性能了,而且如需要遍历,建议使用jdk8的新特性来处理。至于本文主要都是从上到下的模式,其他还有从下到上的查询以及同级别的查找,这里就不一一列举了,熟悉本文后可以灵活变通。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值