C#学习笔记-组合模式

时间:2022-09-26 11:46:39

什么是组合模式?

  组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。

               组合模式使得用户对单个对象和组合对象的使用具有一致性。

何时使用组合模式?

  当需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,同意地使用组合结构中的所有对象时,就应该考虑用组合模式。

组合模式的组成

  Component():组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。

        声明一个接口用于访问和管理Component的子部件。

  Leaf():在组合中表示叶节点对象,叶节点没有子节点。

  Composite():定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove

组合模式具体实现

组合模式的结构

  C#学习笔记-组合模式 

组合模式的实现:

Component():

         abstract class Component
{
protected string name;
public Component(string name)
{
this.name = name;
}
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Diaplay(int depth);
}

Leaf():

        class Leaf : Component
{
public Leaf(string name) : base(name)
{ } public override void Add(Component c)
{
Console.WriteLine("Cannot add a leaf");
} public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
} public override void Remove(Component c)
{
Console.WriteLine("Cannot remove from a leaf");
}
}

Composite():

         class Composite : Component
{
private List<Component> children = new List<Component>();
public Composite(string name) : base(name)
{ } public override void Add(Component c)
{
children.Add(c);
} public override void Diaplay(int depth)
{
//将 System.String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值
Console.WriteLine(new String('-', depth) + name);
foreach(Component component in children)
{
component.Diaplay(depth + );
}
} public override void Remove(Component c)
{
children.Remove(c);
}
}

主函数调用:

        static void Main(string[] args)
{
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB")); root.Add(comp); Composite comp2 = new Composite("Composite XY");
comp2.Add(new Leaf("Leaf XYA"));
comp2.Add(new Leaf("Leaf XYB")); comp.Add(comp2); root.Add(new Leaf("Leaf C")); Leaf leaf = new Leaf("Leaf D");
root.Add(leaf);
root.Remove(leaf); root.Diaplay(); Console.Read();
}

实现效果:

  C#学习笔记-组合模式

实例解析

  为了深化理解,我们准备一个具体的实例来分析。

  C#学习笔记-组合模式

分析:

  C#学习笔记-组合模式

具体实现:

     class Program
{
static void Main(string[] args)
{
ConcreteCompany root = new ConcreteCompany("北京公司总部");
root.Add(new HRDepartment("北京公司总部人力资源部"));
root.Add(new FinanceDepartment("北京公司总部财务部")); ConcreteCompany com = new ConcreteCompany("上海分公司");
com.Add(new HRDepartment("上海分公司人力资源部"));
com.Add(new FinanceDepartment("上海分公司财务部")); root.Add(com); ConcreteCompany com2 = new ConcreteCompany("南京办事处");
com2.Add(new HRDepartment("南京办事处人力资源部"));
com2.Add(new FinanceDepartment("南京办事处财务部")); com.Add(com2); ConcreteCompany com3 = new ConcreteCompany("杭州办事处");
com3.Add(new HRDepartment("杭州办事处人力资源部"));
com3.Add(new FinanceDepartment("杭州办事处财务部"));
com.Add(com3); Console.WriteLine("\n结构图:");
root.Diaplay(); Console.WriteLine("\n职责:");
root.LineOfDuty();
Console.Read();
}
}
abstract class Company
{
protected string name;
public Company(string name)
{
this.name = name;
}
public abstract void Add(Company c);
public abstract void Remove(Company c);
public abstract void Diaplay(int depth);
public abstract void LineOfDuty();
}
class ConcreteCompany : Company
{
private List<Company> children = new List<Company>();
public ConcreteCompany(string name) : base(name)
{ } public override void Add(Company c)
{
children.Add(c);
} public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
foreach(Company company in children)
{
company.Diaplay(depth + );
}
} public override void LineOfDuty()
{
foreach(Company component in children)
{
component.LineOfDuty();
}
} public override void Remove(Company c)
{
children.Remove(c);
}
}
class HRDepartment : Company
{
public HRDepartment(string name) : base(name)
{
} public override void Add(Company c)
{ } public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
} public override void LineOfDuty()
{ Console.WriteLine("{0} 员工招聘培训管理", name); } public override void Remove(Company c)
{ }
}
class FinanceDepartment : Company
{
public FinanceDepartment(string name) : base(name)
{ } public override void Add(Company c)
{ } public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
} public override void LineOfDuty()
{
Console.WriteLine("{0} 公司财务收支管理", name);
} public override void Remove(Company c)
{ }
}

备注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。