简介:就是树状图结构的多个类
-
Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
-
Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
-
Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。
package composite;
import java.security.Provider;
import java.util.ArrayList;
import java.util.List;
//总公司-分公司-部门
public class Make {
public static void main(String[] args) {
ConcreteCompany root = new ConcreteCompany("沈阳总公司");
root.Add(new HRDepartment("总公司人力资源部"));
root.Add(new FinanceDepartment("总公司财务部"));
ConcreteCompany anshan = new ConcreteCompany("鞍山分公司");
root.Add(anshan);
anshan.Add(new HRDepartment("鞍山分公司人力资源部"));
anshan.Add(new FinanceDepartment("鞍山分公司财务部"));
ConcreteCompany fushun = new ConcreteCompany("抚顺分公司");
root.Add(fushun);
fushun.Add(new HRDepartment("抚顺分公司人力资源部"));
fushun.Add(new FinanceDepartment("抚顺分公司财务部"));
System.out.println("结构图:");
root.Display(1);
System.out.println("职责:");
root.LineOfDuty();
/**
* 结构图:
* -沈阳总公司
* ---总公司人力资源部
* ---总公司财务部
* ---鞍山分公司
* -----鞍山分公司人力资源部
* -----鞍山分公司财务部
* ---抚顺分公司
* -----抚顺分公司人力资源部
* -----抚顺分公司财务部
* 职责:
* 总公司人力资源部员工招聘培训管理
* 总公司财务部公司财务收支管理
* 鞍山分公司人力资源部员工招聘培训管理
* 鞍山分公司财务部公司财务收支管理
* 抚顺分公司人力资源部员工招聘培训管理
* 抚顺分公司财务部公司财务收支管理
*/
}
}
//抽象公司类
abstract class Company {
String name;
public Company(String name) {
this.name = name;
}
public abstract void Add(Company c);//添加 枝杈 或者 叶子
public abstract void Remove(Company c);//移除 枝杈 或者 叶子
public abstract void Display(int depth);//显示
public abstract void LineOfDuty();//履行职责
}
//公司类 (枝杈)
class ConcreteCompany extends Company {
private List<Company> children = new ArrayList<>();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void Add(Company c) {
children.add(c);
}
@Override
public void Remove(Company c) {
children.remove(c);
}
@Override
public void Display(int depth) {
System.out.print("-");
for(int i = 1; i < depth; i++) {
System.out.print("-");
}
System.out.println(this.name);
for (Company c:children) {
c.Display(depth + 2);
}
}
@Override
public void LineOfDuty() {
for (Company c:children) {
c.LineOfDuty();
}
}
}
//部门类 (叶子)
class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
@Override
public void Add(Company c) {
}
@Override
public void Remove(Company c) {
}
@Override
public void Display(int depth) {
for(int i = 1; i < depth; i++) {
System.out.print("-");
}
System.out.println("-" + this.name);
}
@Override
public void LineOfDuty() {
System.out.println(this.name + "员工招聘培训管理");
}
}
//部门类 (叶子)
class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
@Override
public void Add(Company c) {
}
@Override
public void Remove(Company c) {
}
@Override
public void Display(int depth) {
for(int i = 1; i < depth; i++) {
System.out.print("-");
}
System.out.println("-" + this.name);
}
@Override
public void LineOfDuty() {
System.out.println(this.name + "公司财务收支管理");
}
}
缺点:
组合模式的主要缺点如下:
-
破坏了“单一职责原则”。
-
在增加新构件时很难对容器中的构件类型进行限制。有时候我们希望一个容器中只能有某些特定类型的对象,例如在某个文件夹中只能包含文本文件,使用组合模式时,不能依赖类型系统来施加这些约束,因为它们都来自于相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。
优点
组合模式的主要优点如下:
-
组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
-
客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。
-
在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
-
组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的
适用环境
在以下情况下可以考虑使用组合模式:
-
在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
-
在一个使用面向对象语言开发的系统中需要处理一个树形结构。
-
在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。
-
树形结构,但对树形结构的控制却非常简单。