设计模式 <结构型> | 组合模式

组合模式(Composite Design Pattern)

组合模式将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。

结构图:

角色:

  1. 抽象节点(Component):
    1. 透明模式下把所有行为都再放抽象节点中,让不同层次的结构都具备一致行为
    2. 安全组合模式是只规定各个节点的最基础的一致行为,而把组合节点的方法放到节点自身中。
  2. 叶子节点(Leaf):树的基本结构,它不包含子项目。
  3. 树枝节点(Composite):含叶节点的单位,树枝不知道其子项目所属的具体类, 它只通过通用的组件接口与其子项目交互。

适用场景:

  1. 需要对象表达有层次的结构时。

优点:

  1. 利用多态和递归机制更方便地使用复杂树结构。
  2. 无需更改现有代码就可以在应用中添加新元素。

缺点

  1. 设计更加复杂,增加代码复杂度。

代码(C#)

透明模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/// <summary>
/// 抽象节点
/// </summary>
public abstract class Component
{
public string Name { get; set; }

public Component(string name)
{
Name = name;
}

public abstract void Add(Component company);
public abstract void Remove(Component company);
public abstract void Get(int index);
}

/// <summary>
/// 树枝节点
/// </summary>
public class Composite : Component
{
private List<Component> c = new();


public Composite(string name) : base(name)
{
}

public override void Add(Component company)
{
c.Add(company);
}

public override void Remove(Component company)
{
c.Remove(company);
}

public override void Get(int index)
{
Console.WriteLine($"{new string('-', index)}{Name}");
foreach (var item in c)
{
item.Get(index + 2);
}
}
}

/// <summary>
/// 叶子节点
/// </summary>
public class Leaf : Component
{
public Leaf(string name) : base(name)
{
}

public override void Add(Component company)
{
throw new NotImplementedException();
}

public override void Remove(Component company)
{
throw new NotImplementedException();
}

public override void Get(int index)
{
Console.WriteLine($"{new string('-', index)}{Name}");
}
}

var component = new Composite("技术部");

var kaifa = new Composite("开发部");
component.Add(kaifa);

var xiaoming = new Leaf("小明");
kaifa.Add(xiaoming);

var ceshi = new Composite("测试");
component.Add(ceshi);
var xiaohong = new Leaf("小红");
ceshi.Add(xiaohong);

component.Get(2);

安全模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/// <summary>
/// 抽象节点
/// </summary>
public abstract class Component
{
public string Name { get; set; }

public Component(string name)
{
Name = name;
}

public abstract void print(int index);
}

/// <summary>
/// 树枝节点
/// </summary>
public class Composite : Component
{
private List<Component> c = new();


public Composite(string name) : base(name)
{
}

public void Add(Component company)
{
c.Add(company);
}

public void Remove(Component company)
{
c.Remove(company);
}


public override void print(int index)
{
Console.WriteLine($"{new string('-', index)}{Name}");
foreach (var item in c)
{
item.print(index + 2);
}
}

public Component Get(int index)
{
return c[index];
}
}

/// <summary>
/// 叶子节点
/// </summary>
public class Leaf : Component
{
public Leaf(string name) : base(name)
{
}

public Component Get()
{
return this;
}

public override void print(int index)
{
Console.WriteLine($"{new string('-', index)}{Name}");
}
}

最后

使用组合模式的前提在于,业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。


设计模式 <结构型> | 组合模式
http://example.com/posts/44993.html
作者
她微笑的脸y
发布于
2023年3月2日
许可协议