设计模式之组合模式

组合模式

1.需求: 编写程序展示学校的院系要求

要在一个页面中展示出学校的院系组成,一个学校中有多个学院,一个学院中有多个系。

图示:
在这里插入图片描述

2.解决方案:
  1. 将学院看做是学校的子类,系看做学院的子类

  2. 实际上要求是体现出学校的院系组成,一个学校有多个学院,一个学院有多个系。因此这种方案不能很好实现管理操作。比如对学院,系的添加,删除,遍历等(所以不建议使用继承关系完成该需求)

  3. 解决问题: 将学校,院和系都看作组织结构,他们之间没有继承关系。而是一种树形结构,可以更好地实现管理操作(组合模式)【相当于上下级组织 而不是父亲儿子的继承关系】

3.组合模式介绍
  • 组合模式(Composite Pattern),又称为部分整体模式,它创建了对象组的树形结构,将对象组合成树形结构以表示"整体-部分"的层次关系
  • 组合模式属于结构型模式,依据树形结构来组合对象,用来表示 部分和整体的层次关系
  • 组合模式让对象对单个对象和组合对象的访问具有一致性,即: 组合能让客户以一致的方式处理个别对象以及组合对象
  • 当我们要处理的对象可以生成一棵树型结构(参考二叉树),而我们要对树上的枝和叶子进行操作时,可以考虑使用组合模式。
  • 组合模式的角色
    • Component: 抽象角色,为要组合的对象实现统一接口
    • Leaf: 叶子节点
    • Composite:枝节点,实例化Component接口的有关操作
    • uml:

在这里插入图片描述

代码演示:
package composite;

import java.util.ArrayList;
import java.util.List;

//组合模式
public class Demo {
	// 1.Component: 组合中对象声明的抽象类,适当情况下支持所有类的共有行为,用来访问和管理所有子部件
	 public static abstract class OrganizationComponent {
		private String name;// 子部件名
		private String des;// 子部件的说明
		// 日常get set
		
		public String getName() {
			return name;
		}

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

		public String getDes() {
			return des;
		}

		public void setDes(String des) {
			this.des = des;
		}
		//默认构造
		  public OrganizationComponent(String name, String des) {
		        super();
		        this.name = name;
		        this.des = des;
		    }
		/**
		 * 共有方法: 1.添加 add(默认实现) 2.删除 remove(默认实现)
		 */
		protected void add(OrganizationComponent organization) {
			throw new UnsupportedOperationException("默认实现的添加方法");
		}

		protected void remove(OrganizationComponent organization) {
			throw new UnsupportedOperationException("默认实现的删除方法");
		}

	
		// 打印当前的信息 抽象方法
		public abstract void print();

	}

	// 2.Composite: 顶层实体类: 大学
	 public static class University extends OrganizationComponent {
		// 采用List存储信息
		List<OrganizationComponent> organizationComponents = new ArrayList<>();
		
		public University(String name, String des) {
			super(name, des);
			// TODO Auto-generated constructor stub
		}

		// 重写get方法
		@Override
		public String getName() {
			return super.getName();
		}

		@Override
		public String getDes() {
			return super.getDes();
		}

	

		// 重写add方法
		@Override
		protected void add(OrganizationComponent organization) {
			// 加入元素
			organizationComponents.add(organization);
		}

		@Override
		protected void remove(OrganizationComponent organization) {
			// 移除元素
			organizationComponents.add(organization);
		}

		@Override
		public void print() {
			  System.out.println("-----------------"+getName()+"-----------------");
			for (OrganizationComponent demo : organizationComponents) {
				demo.print();
			}
		}
	}

	// 3.Composite: 实体类 : 院系 (和 University的逻辑类似)
	 public static class College extends OrganizationComponent {

		public College(String name, String des) {
			super(name, des);
			// TODO Auto-generated constructor stub
		}

		// 重写get方法
		@Override
		public String getName() {
			return super.getName();
		}

		@Override
		public String getDes() {
			return super.getDes();
		}

		// 采用List存储信息
		List<OrganizationComponent> organizationComponents = new ArrayList<>();

		// 重写add方法
		@Override
		protected void add(OrganizationComponent organization) {
			// 加入元素
			organizationComponents.add(organization);
		}

		@Override
		protected void remove(OrganizationComponent organization) {
			// 移除元素
			organizationComponents.add(organization);
		}

		@Override
		public void print() {
			  System.out.println("-----------------"+getName()+"-----------------");
			for (OrganizationComponent demo : organizationComponents) {
				demo.print();
			}
		}
	}

	// 4.叶子类 : Department
	public static class Department extends OrganizationComponent {
		public Department(String name, String des) {
			super(name, des);
		}

		//Department已经属于叶子节点了 无需add和remove
		 @Override
		    public String getName() {
		        return super.getName();
		    }

		    @Override
		    public String getDes() {
		        return super.getDes();
		    }

		@Override
		public void print() {
			System.out.println(this.getName());
		}
	}
	
	//client
	public static void main(String[]args) {
		  //从大到小进行对象的创建
        OrganizationComponent university = new University("江西农业大学", "我的大学");
        //创建学校
        OrganizationComponent college = new College("软件学院", "我的学院");
        //创建学院1
        OrganizationComponent college2 = new College("经管学院", "隔壁学院");
        
        //学院加专业
        college.add(new Department("物联网工程", "我的专业"));
        college.add(new Department("软件工程", "其他专业"));
        college2.add(new Department("农林经济管理", "其他专业1"));
        college2.add(new Department("市场营销", "其他专业2"));
        
        //学校加学院
        university.add(college);
        university.add(college2);
        
        //打印
        university.print();
       
		
	}
}

在这里插入图片描述

组合模式的一些细节

优点

  1. 很形象地表示出了树形结构
  2. 节点增加很方便(扩展性强),无需修改底层抽象方法

缺点

  1. 使用组合模式的时候,叶子节点和树枝都是实现类,违反了依赖倒转原则(高层模块不能依赖底层模块,应该统一依赖于接口)
  2. 如果节点和叶子之间有较多差异的话,像是方法和属性很多不一样(即具有较低的抽象性),很难使用组合模式

使用环境

  1. 在一个系统中可以分离出树形结构,分离叶子对象,枝对象和顶层容器,(类似树形菜单,文件,文件夹的管理)
  2. 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们

参考文章: https://www.jianshu.com/p/c658fecbaa7b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值