C#组合模式(Composite Pattern)实例详解:构建企业部门结构
本文通过构建“总公司-分公司-部门”的树形结构,详细解析C#中组合模式的原理与实现。涵盖抽象组件类、容器组件类及叶子节点类的定义,以及统一处理原子对象和组合对象的方法调用。
组合模式的核心目标
组合模式(Composite Pattern)是一种结构型设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。其核心目的是让用户对单个对象(叶子节点)和组合对象(容器节点)的使用保持一致性,无需区分它们是独立对象还是对象组合。
在本例中,我们将模拟一个公司的组织架构:
- 抽象公司类 (Company):定义添加、删除、显示和业务履行等通用接口。
- 具体公司类 (ConcreteCompany):作为容器,管理子节点,支持递归操作。
- 具体部门类 (FinanceDepartment/HRdepartment):作为叶子节点,只实现具体业务,不支持添加子节点。
第1步:定义抽象组件基类 Company
这是组合结构的骨架。它定义了所有组件(无论是公司还是部门)都必须具备的功能:添加子项、移除子项、显示自身信息以及履行职责。对于叶子节点而言,这些方法可以是空实现或抛出异常,以保证接口的一致性。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public 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 Display(int depth);
public abstract void LineOfDuty();
}
}
第2步:实现容器节点 ConcreteCompany
ConcreteCompany 代表具有子节点的公司或部门。它内部维护了一个 List<Company> 集合来存储其直接下属。关键逻辑在于递归:
- Add/Remove:直接操作列表。
- Display:打印自身名称后,遍历并调用所有子节点的 Display 方法,深度加2,从而形成层级缩进效果。
- LineOfDuty:委托给所有子节点执行各自的具体业务。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public 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 Remove(Company c)
{
children.Remove(c);
}
public override void Display(int depth)
{
// 使用连字符表示层级深度
Console.WriteLine(new String('-',depth)+name);
foreach(Company component in children)
{
// 递归调用,深度增加
component.Display(depth+2);
}
}
public override void LineOfDuty()
{
foreach(Company component in children)
{
// 委托子节点执行具体职责
component.LineOfDuty();
}
}
}
}
第3步:实现叶子节点 FinanceDepartment
财务部门是具体的职能部门,没有下属机构。因此,在重写基类方法时:
- Add/Remove:留空,因为叶子节点不能有子节点。
- Display:仅打印自身名称和层级。
- LineOfDuty:输出具体的财务职能描述。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class FinanceDepartment:Company
{
public FinanceDepartment(string name) : base(name) { }
public override void Add(Company c)
{
// 叶子节点不支持添加子节点
}
public override void Remove(Company c)
{
// 叶子节点不支持移除子节点
}
public override void Display(int depth)
{
Console.WriteLine(new String('-',depth)+name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0} 财务支付管理",name);
}
}
}
第4步:实现叶子节点 HRdepartment
人力资源部门的实现逻辑与财务部类似,同样作为叶子节点存在,只承担招聘培训管理的职责。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class HRdepartment:Company
{
public HRdepartment(string name)
:base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new String('-',depth)+name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0} 招聘培训管理",name);
}
}
}
第5步:构建结构并测试 Program.cs
在 Main 方法中,我们按照“北京总部 → 上海分公司 → 南京/杭州分部”的逻辑构建整个树形结构。最后调用根节点的 Display 方法,即可看到完整的层级打印结果;调用 LineOfDuty 则会执行所有下属单位的业务逻辑。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// 1. 创建根节点:北京总共司
ConcreteCompany root = new ConcreteCompany("北京总共司");
root.Add(new HRdepartment("人力部"));
root.Add(new FinanceDepartment("财务部"));
// 2. 创建上海分公司及其下属
ConcreteCompany comp = new ConcreteCompany("上海分公司");
comp.Add(new HRdepartment("分工司人力部"));
comp.Add(new FinanceDepartment("分公司财务部"));
root.Add(comp); // 将上海分公司加入北京总部
// 3. 创建南京分部并加入上海分公司
ConcreteCompany comp1 = new ConcreteCompany("南京分部");
comp1.Add(new HRdepartment("南京人力部"));
comp1.Add(new FinanceDepartment("南京财务部"));
comp.Add(comp1);
// 4. 创建杭州分部并加入上海分公司
ConcreteCompany comp2 = new ConcreteCompany("杭洲分部");
comp2.Add(new HRdepartment("杭州人事部"));
comp2.Add(new FinanceDepartment("杭州财务部"));
comp.Add(comp2);
// 5. 打印组织结构树
root.Display(1);
Console.ReadKey();
}
}
}
以上就是C#组合模式构建企业部门结构的详细内容,更多关于C#设计模式的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













