You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

领域驱动设计(DDD)继承实践咨询:CompanyOwner类的推荐实现方案

DDD实体继承场景实现方案解答

问题背景

提问者刚接触领域驱动设计,当前有基础的Employee员工实体类,需要实现公司所有者CompanyOwner的相关逻辑,现有三类实现方案,需要评估最优解。

原有Employee类代码:

public class Employee
{
    public Guid EmployeeID { get; }

    public String Firstname { get; }

    public String Lastname { get; }

    // Constructor
    private Employee(Guid employeeID, String firstname, String lastname)
    {
        EmployeeID = employeeID;
        Firstname = firstname;
        Lastname = lastname;
    }

    // Factory
    public static Employee Create(Guid employeeID, String firstname, String lastname)
    {
        return new Employee(employeeID, firstname, lastname);
    }
}

注:原代码工厂方法遗漏返回值类型,已补全

现有方案评估

方案1:继承Employee类

逻辑思路:公司所有者属于员工,直接继承Employee类实现,需要修改父类属性为protected set权限。
该方案的核心问题是违背DDD优先组合而非继承的设计原则,继承是强耦合的is-a关系,无法支持一个员工同时担任多家公司所有者的业务场景,且修改父类访问权限会破坏原有实体的封装性,后续扩展其他员工角色时会出现类爆炸问题,不推荐使用。

对应代码:

public class CompanyOwner : Employee
{
    // ID for the owner (primary key in database)
    public Guid CompanyOwnerID { get; }

    // Constructor
    private CompanyOwner(Guid companyOwnerID, Guid employeeID, String firstName, String lastName)
    {
        CompanyOwnerID = companyOwnerID;        
        EmployeeID = employeeID;        
        Firstname = firstname;
        Lastname = lastname;
    }

    // Factory        
    public static CompanyOwner Create(Guid companyOwnerID, Guid employeeID, String firstname, String lastname)
    {
        return new CompanyOwner(companyOwnerID, employeeID, firstname, lastname);
    }
}

方案2:组合Employee属性

逻辑思路:CompanyOwner类中内置Employee类型的属性保存员工信息,直接调用原有Employee的工厂方法初始化。
该方案是DDD处理角色类场景的标准实践,耦合度低、扩展性强,唯一的属性访问不够简洁的问题可以通过增加透传属性轻松解决,是最优选择。

对应代码:

public class CompanyOwner
{
    // Unique ID for the owner (primary key)
    public Guid CompanyOwnerID { get; }

    // Employee info
    public Employee EmployeeInfo { get; }
   
    // Constructor
    private CompanyOwner(Guid companyOwnerID, Guid employeeID, String firstName, String lastName)
    {
        CompanyOwnerID = companyOwnerID;

        // Calling factory-method of Employee-class to set employee-info
        EmployeeInfo = Employee.Create(employeeID, firstName, lastName);
    }

    // Factory        
    public static CompanyOwner Create(Guid companyOwnerID, Guid employeeID, String firstname, String lastname)
    {
        return new CompanyOwner(companyOwnerID, employeeID, firstname, lastname);
    }
}

方案3:Employee类新增IsOwner标记

逻辑思路:移除CompanyOwner类,直接在Employee实体中加IsOwner字段标记是否为公司所有者。
该方案提问者已明确不可行,确实不符合员工可担任多家公司所有者的业务规则,且CompanyOwnerID主键无法放到Employee类中,排除该方案。

对应代码:

public class Employee
{
    public Guid EmployeeID { get; }

    public String Firstname { get; }

    public String Lastname { get; }

    public Boolean IsOwner { get; }

    // Constructor
    private Employee(Guid employeeID, String firstname, String lastname, Boolean isOwner)
    {
        EmployeeID = employeeID;
        Firstname = firstname;
        Lastname = lastname;
        IsOwner = isOwner;
    }

    // Factory
    public static Employee Create(Guid employeeID, String firstname, String lastname, Boolean isOwner)
    {
        return new Employee(employeeID, firstname, lastname, isOwner);
    }
}

优化后的推荐实现

针对方案2的属性访问问题,新增透传属性优化,最终实现代码如下:

public class CompanyOwner
{
    public Guid CompanyOwnerID { get; }
    public Employee EmployeeInfo { get; }

    // 透传员工属性,简化调用
    public Guid EmployeeID => EmployeeInfo.EmployeeID;
    public string Firstname => EmployeeInfo.Firstname;
    public string Lastname => EmployeeInfo.Lastname;

    private CompanyOwner(Guid companyOwnerID, Employee employee)
    {
        // 可补充参数合法性校验
        if (companyOwnerID == Guid.Empty) throw new ArgumentException("所有者ID不能为空", nameof(companyOwnerID));
        EmployeeInfo = employee ?? throw new ArgumentNullException(nameof(employee));
        CompanyOwnerID = companyOwnerID;
    }

    public static CompanyOwner Create(Guid companyOwnerID, Guid employeeID, string firstname, string lastname)
    {
        var employee = Employee.Create(employeeID, firstname, lastname);
        return new CompanyOwner(companyOwnerID, employee);
    }

    // 重载工厂方法,支持传入已有的Employee实例
    public static CompanyOwner Create(Guid companyOwnerID, Employee employee)
    {
        return new CompanyOwner(companyOwnerID, employee);
    }
}

该实现的优势:

  • 完全保留原有Employee类的封装性,符合开闭原则,不需要修改任何原有代码
  • 天然支持一个员工对应多个CompanyOwner实例,匹配多公司所有者的业务需求
  • 透传属性保证了调用的简洁性,不需要嵌套访问员工信息
  • 后续扩展所有者专属逻辑(如股权比例、关联公司ID、所有者权限等)不会影响员工类的逻辑

内容的提问来源于stack exchange,提问作者Marcus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:06:03