组合模式:Composite Pattern,又叫作整体-部分(Part-Whole)模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行表示,使得客户对单个对象和组合对象的使用具有一致性,属于结构型设计模式

    组合模式一般用于描述整体和部分的关系,将对象组织到树形结构中

    • 顶层的节点被称为根节点
    • 根节点下面可以包含树枝节点和叶子节点
    • 树节点下面又可以包含树枝节点和叶子节点

    在组合模式中,整个树形结构中的对象都属于同一种类型,带来的好处就是用户不需要辨别是树枝节点还是叶子节点,可以直接进行操作,给用户的使用带来极大的便利

    组合模式的一般用途:

    • 希望客户端可以忽略组合对象和单个对象的差异
    • 对象层次具备整体和部分,呈树形结构

    UML 图:
    image.png
    通用写法:

    1. public class CompositeDemo {
    2. public static void main(String[] args) {
    3. // 创建根结点
    4. Component root = new Composite("root");
    5. // 创建一个树枝节点
    6. Component branchA = new Composite("---branchA");
    7. Component branchB = new Composite("------branchB");
    8. // 创建叶子节点
    9. Component leafA = new Leaf("------leafA");
    10. Component leafB = new Leaf("---------leafB");
    11. Component leafC = new Leaf("---leafC");
    12. // 节点组装
    13. root.addChild(branchA);
    14. root.addChild(leafC);
    15. branchA.addChild(leafA);
    16. branchA.addChild(branchB);
    17. branchB.addChild(leafB);
    18. String result = root.operation();
    19. System.out.println(result);
    20. }
    21. // 抽象节点
    22. static abstract class Component {
    23. protected String name;
    24. public Component(String name) {
    25. this.name = name;
    26. }
    27. public abstract String operation();
    28. public boolean addChild(Component component) {
    29. throw new UnsupportedOperationException("addChild not supported");
    30. }
    31. public boolean removeChild(Component component) {
    32. // 直接抛异常而非抽象方法的原因:
    33. // 使用了抽象方法,则子类必须实现,这样就体现不了各类子类的差异
    34. // 而使用抛异常,则子类无需实现与本身功能无关的方法
    35. throw new UnsupportedOperationException("removeChild not supported");
    36. }
    37. public Component getChild(int index) {
    38. throw new UnsupportedOperationException("getChild not supported");
    39. }
    40. }
    41. // 树枝节点
    42. static class Composite extends Component {
    43. private List<Component> components;
    44. public Composite(String name) {
    45. super(name);
    46. this.components = new ArrayList<>();
    47. }
    48. @Override
    49. public String operation() {
    50. StringBuilder builder = new StringBuilder(this.name);
    51. for (Component component : this.components) {
    52. builder.append("\n");
    53. builder.append(component.operation());
    54. }
    55. return builder.toString();
    56. }
    57. @Override
    58. public boolean addChild(Component component) {
    59. return components.add(component);
    60. }
    61. @Override
    62. public boolean removeChild(Component component) {
    63. return components.remove(component);
    64. }
    65. @Override
    66. public Component getChild(int index) {
    67. return components.get(index);
    68. }
    69. }
    70. // 叶子节点
    71. static class Leaf extends Component {
    72. public Leaf(String name) {
    73. super(name);
    74. }
    75. @Override
    76. public String operation() {
    77. return this.name;
    78. }
    79. }
    80. }