一、什么是组合模式
将对象组合成树状结构以表示整体和部分的层次结构
组合模式使得用户对单个对象和组合对象的使用具有一致性,提供了一种结构,允许我们忽略对象与集合之间的差别。组合模式又分为透明组合模式和安全组合模式,透明组合模式不区分树枝和树叶,安全组合模式抽象基类只保留共有部分,树枝独有的自己实现。
UML图
Component: 基类,包含添加/移除/显示的基础功能,
Composite:具体实现像是一层一层的嵌套关系
Leaf:分支最末端,只有显示功能
二、适用场景
当对象以整体和部分的层级关系出现,从使用层面不需要区分整体和部分,具备一致性.比如文件夹文件系统,文件夹下面可以有 文件也可以有子文件夹,子文件夹也可以有文件和子文件夹, 但我们对于不同层级的文件夹操作是一致的。比如生活中的购物袋,有大有小,购物袋可以装商品,也可以装购物袋。
三、优缺点
优点
忽略对象与组合的层次关系,可对此进行一致的操作
添加树枝或树叶节点很方便,不会破坏原有层级。
缺点
系统可能过于庞大而复杂
违背接口隔离原则
四、大话中的例子
总公司与分公司的关系,总公司下有各个地区的分公司,还有自己的各级职能部门, 分公司下也有自己的办事处还有自己的职能部门。总公司就像一个树的根,分公司和它的只能部分就是树枝和树叶 ,树枝下面还可以有树枝和树叶。
五、我的例子
using System;
using System.Collections.Generic;
namespace CompsiteMode
{
class Program
{
static void Main(string[] args)
{
Bag smallBag1 = new Bag("小袋子1");
Bag smallBag2 = new Bag("小袋子2");
Bag normBag = new Bag("中袋子");
Bag BigBag = new Bag("大袋子");
Goods apple = new Goods("苹果", 8, 6);
Goods banana = new Goods("香蕉", 2, 10);
Goods water = new Goods("纯净水", 3, 1);
Goods ErGuoTou = new Goods("二锅头", 16, 2);
Goods reBull = new Goods("红牛", 6, 3);
smallBag1.Add(apple);
smallBag2.Add(banana);
normBag.Add(water);
normBag.Add(reBull);
normBag.Add(smallBag1);
BigBag.Add(ErGuoTou);
BigBag.Add(smallBag2);
BigBag.Add(normBag);
BigBag.Display(1);
Console.WriteLine("总计:{0}", BigBag.LineOfDuty());
Console.ReadKey();
}
}
/// <summary>
/// 抽象物品
/// </summary>
abstract class Articles
{
protected string name;
public Articles(string name)
{
this.name = name;
}
public abstract void Display(int depth);
public abstract int LineOfDuty();
}
/// <summary>
/// 袋子
/// </summary>
class Bag : Articles
{
List<Articles> children = new List<Articles>();
public Bag(string name) : base(name)
{
}
public void Add(Articles bag)
{
children.Add(bag);
}
public void Remove(Articles bag)
{
children.Remove(bag);
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
foreach (var item in children)
{
item.Display(depth + 2);
}
}
public override int LineOfDuty()
{
int temp = 0;
foreach (var item in children)
{
temp += item.LineOfDuty();
}
return temp;
}
}
/// <summary>
/// 商品
/// </summary>
class Goods : Articles
{
int price;
int num;
public Goods(string name, int price, int num) : base(name)
{
this.price = price;
this.num = num;
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
}
public override int LineOfDuty()
{
Console.WriteLine("{0}-单价:{1},数量:{2},总价:{3}", name, price, num, price * num);
return price * num;
}
}
}
运行结果
PS:组合模式如果层级很多,那就会显得过于复杂,层级关系混乱。从感觉上看像是一种递归关系的变异。