公司管理系统示例:
1.Component:
public abstract class Company { protected string name; public Company(string name) { this.name = name; } public abstract void Add(Company company); public abstract void Remove(Company company); public abstract void Display(int depth); public abstract void LineOfDuty(); }
2.Composite:
public class ConcreteCompany:Company { private IList<Company> companys = new List<Company>(); public ConcreteCompany(string name) :base(name) { } public override void Add(Company company) { companys.Add(company); } public override void Remove(Company company) { companys.Remove(company); } public override void Display(int depth) { Console.WriteLine(new string('-',depth) + name); foreach(var company in companys) { company.Display(depth + 2); } } public override void LineOfDuty() { foreach(var company in companys) { company.LineOfDuty(); } } }
3.Leaf:
public class HRDepartment:Company { public HRDepartment(string name) :base(name) { } public override void Add(Company company) { } public override void Remove(Company company) { } public override void Display(int depth) { Console.WriteLine(new string('-', depth) + name); } public override void LineOfDuty() { Console.WriteLine("{0} 员工招聘培训管理",name); } }
public class FinanceDepartment:Company { public FinanceDepartment(string name) : base(name) { } public override void Add(Company company) { } public override void Remove(Company company) { } public override void Display(int depth) { Console.WriteLine(new string('-', depth) + name); } public override void LineOfDuty() { Console.WriteLine("{0} 公司财务收支管理",name); } }
4.客户端代码:
class Program { static void Main(string[] args) { Company rootCompany = new ConcreteCompany("北京总公司"); rootCompany.Add(new HRDepartment("总公司人力资源部")); rootCompany.Add(new FinanceDepartment("总公司财务部")); Company eastCompany = new ConcreteCompany("华东分公司"); eastCompany.Add(new HRDepartment("华东分公司人力资源部")); eastCompany.Add(new FinanceDepartment("华东分公司财务部")); rootCompany.Add(eastCompany); Company shanghaiCompany = new ConcreteCompany("上海办事处"); shanghaiCompany.Add(new HRDepartment("上海办事处人力资源部")); shanghaiCompany.Add(new FinanceDepartment("上海办事处财务部")); eastCompany.Add(shanghaiCompany); Console.WriteLine("机构图:"); rootCompany.Display(1); Console.WriteLine("职责:"); rootCompany.LineOfDuty(); } }
透明方式:Component中声明所有用来管理子对象的方法,其中包括Add、Move等。这样实现Componet接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以实现它是完全没有意义的。
安全方式:Componet中不去声明Add和Remove方法,那么子类Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法。不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用要做相应的判断,带来了不便。