组合模式又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。它使得用户对单个对象和组合对象的访问具有一致性。

    【角色】

    • 抽象构件(Component):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
    • 叶子构件(Leaf):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。 对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
    • 容器构件(Composite):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

    组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。

    1. /**
    2. * 组织抽象类
    3. */
    4. public abstract class Organization {
    5. // 名称
    6. private String name;
    7. public Organization(String name) {
    8. this.name = name;
    9. }
    10. /**
    11. * 添加
    12. */
    13. protected void add(Organization org) {
    14. throw new UnsupportedOperationException();
    15. }
    16. /**
    17. * 输出
    18. */
    19. protected abstract void print();
    20. public void setName(String name) {
    21. this.name = name;
    22. }
    23. public String getName() {
    24. return this.name;
    25. }
    26. }
    1. /**
    2. * 学校
    3. */
    4. public class School extends Organization {
    5. /**
    6. * 学院
    7. */
    8. private List<Organization> orgList = new ArrayList<>();
    9. public School(String name) {
    10. super(name);
    11. }
    12. @Override
    13. public void add(Organization org) {
    14. orgList.add(org);
    15. }
    16. @Override
    17. protected void print() {
    18. System.out.println(getName());
    19. for (Organization org : orgList) {
    20. org.print();
    21. }
    22. }
    23. }
    1. /**
    2. * 学院
    3. */
    4. public class College extends Organization {
    5. /**
    6. * 系
    7. */
    8. private List<Organization> orgList = new ArrayList<>();
    9. public College(String name) {
    10. super(name);
    11. }
    12. @Override
    13. public void add(Organization org) {
    14. orgList.add(org);
    15. }
    16. @Override
    17. public void print() {
    18. System.out.println("\t" + getName());
    19. for (Organization org : orgList) {
    20. org.print();
    21. }
    22. }
    23. }
    1. /**
    2. * 系
    3. */
    4. public class Department extends Organization {
    5. public Department(String name) {
    6. super(name);
    7. }
    8. @Override
    9. protected void print() {
    10. System.out.println("\t\t" + getName());
    11. }
    12. }
    1. public class CombinationTest {
    2. public static void main(String[] args) {
    3. School school = new School("武汉大学");
    4. College college1 = new College("计算机学院");
    5. College college2 = new College("艺术学院");
    6. school.add(college1);
    7. school.add(college2);
    8. Department department1 = new Department("科学与技术");
    9. Department department2 = new Department("动漫设计");
    10. college1.add(department1);
    11. college1.add(department2);
    12. Department department3 = new Department("声乐");
    13. Department department4 = new Department("舞蹈");
    14. college2.add(department3);
    15. college2.add(department4);
    16. school.print();
    17. }
    18. }
    19. ----输出----
    20. 武汉大学
    21. 计算机学院
    22. 科学与技术
    23. 动漫设计
    24. 艺术学院
    25. 声乐
    26. 舞蹈