发行使用构成了“是 - 个“关系(Issue in using Composition for “i

2019-07-30 17:18发布

我已经被一个HR系统开发的系统。 有会计师员工和程序员的员工。 对于加入该公司的第一个月,员工没有给出任何作用。 一个员工都可以是一个会计师,同时程序员。 我有下面的代码所示的设计。

现在,我需要通过实现新的功能,以增强系统:

终止所有会计师。 (终止装置雇员作为IsActive =假的设定状态)。 问题是我不能直接将所有的会计师为不活动,不检查。 我需要检查他是否有任何其他作用。

如何才能做到终止功能更自然的面向对象的改造这些类?

UPDATE

我要寻找的是具有@AlexDev答案EF数据库优先的解决方案模型和数据库架构的答案。

C#代码

List<Accountant> allAccountants =  Get All accountants from database

public class Employee
{
    public int EmpID { get; set; }
    public DateTime JoinedDate { get; set; }
    public int Salary { get; set; }
    public bool IsActive { get; set; }
}


public class Accountant : Employee
{
    public Employee EmployeeData { get; set; }
}

public class Programmer : Employee
{
    public Employee EmployeeData { get; set; }
}

@AlexDev回答

public class Employee
{
...
IList<Role> Roles;
bool isActive;

public void TerminateRole(Role role)
{
    Roles.Remove(role);
    if(Roles.Count == 0)
    {
        isActive = false;
    }
}
}

public class Role
{
 abstract string Name { get;}
}

public class ProgrammerRole : Role
{
 override string Name { get { return "Programmer"; } }
}

参考

  1. DDD的方式获取外部信息
  2. 身高超过组成继承?
  3. 继承VS域模型中枚举的属性
  4. 实体框架:获取库子类对象

Answer 1:

要使用你正在使用你需要的人谁是一名会计和一名程序员,除了新的角色可能会被添加到系统中多重继承结构,不C#中存在。 你应该考虑不同的设计。 一种可能性:

public class Employee
{
    ...
    IList<Role> Roles;
    bool isActive;

    public void TerminateRole(Role role)
    {
        Roles.Remove(role);
        if(Roles.Count == 0)
        {
            isActive = false;
        }
    }
}

public class Role
{
    abstract string Name { get;}
}

public class ProgrammerRole : Role
{
    override string Name { get { return "Programmer"; } }
}

然后,你可以继承为每种类型的角色,你可以决定终止只是一个角色,或全部。



Answer 2:

我正在写一个新的答案,因为从你加入到这个问题的模式我假设你将不会被继承的角色。 此外,如果你正在使用NHibernate不要忘记使用公共虚拟财产。

public class Employee
{
    ...
    public virtual IList<Role> Roles { get; set; }
    public virtual bool isActive { get; set; }

    public virtual void TerminateRole(Role role)
    {
        Roles.Remove(role);
        if(Roles.Count == 0)
        {
            isActive = false;
        }
    }
}

public class Role
{
    public virtual int RoleID { get; set; }
    public virtual string Name { get; set; } 
}

和映射:

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Id(x => x.EmpId);
        Map(x => x.JoinedDate)
        Map(x => x.Salary);
        Map(x => x.IsActive);
        HasManyToMany(x => x.Roles).Cascade.AllDeleteOrphan().Table("EmployeeRole")
    }
}

public class RoleMap : ClassMap<Role>
{
    public RoleMap()
    {
        Id(x => x.RoleID);
        Map(x => x.RoleName);
    }
}


Answer 3:

public abstract class AbstractEmployee
{
    ...
    public abstract bool IsActiveAccountant { get; set; }
    public abstract bool IsActiveProgrammer { get; set; }
    public bool IsActive() { get { return bitwise or of all roles; } }
}

public class NewEmployee : AbstractEmployee
{
    ...
    public override bool IsActiveAccountant { get; set; }
    public override bool IsActiveProgrammer { get; set; }
}

public class Programmer : AbstractEmployee
{
    ...
    public override bool IsActiveAccountant { get; set; }
    public override bool IsActiveProgrammer { get; set; }
}

缺点:

  • 每一个新的系统级角色添加您需要修改类

优点:

  • 你不需要搜索会计师
  • 程序员可以空实现IsActiveAccountant的,因为这个角色是不活动的他们无论如何
  • NewEmployee可以在同一时间有很多角色

如果从引入新角色开销显著,我要坚持搜索



Answer 4:

从我在回答宗教组成了继承?

我会首先检查开始 - 是否存在一个“是”的关系。 如果它存在,我通常检查以下内容:

无论是基类可以被实例化。 也就是说,基类是否可以是非抽象的。 如果可以是非抽象我通常喜欢组成

例如1.会计是一个雇员。 但我不会使用继承,因为一个Employee对象可以被实例化。

如2.书是一个SellingItem。 一个SellingItem不能被实例化 - 它是抽象的概念。 因此,我将使用inheritacne。 所述SellingItem是一个抽象基类(或接口中C#)



文章来源: Issue in using Composition for “is – a “ relationship