C# 系列 Class 设计

C# Family Class Design

我正在为一个应用程序构建一个家庭单元 (class)。我已经做了一些搜索并找到了整个家谱的解决方案,但是这个应用程序不关心定义为 (Father, Mother, Child1, Child+ n)

此应用程序是关于 children(他们可以根据年龄和技能水平进行的活动),但需要参考 parents。 parents 仅用于报告目的,并且需要备案驾驶执照和保险。

正在使用 C# 和 EF Code First 构建应用程序。 None 的数据库注释元素已添加到 class 中,但这不是问题所在。

以下是我的 class。主要业务规则规定每个兄弟姐妹将有 his/her 自己的记录,但他们需要链接在一起,因此如果 parents 住在一起,则只发送一封邮件(电子或蜗牛)。如果parents离婚了,需要发两封信(或邮件)

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string Suffix { get; set; }
    public string Sex { get; set; }
    public DateTime DOB { get; set; }
}

public class Youth : Person
{
    public string CurrentGrade { get; set; }
    public Adult Mother { get; set; }
    public Adult Father { get; set; }
    public Adult ICE { get; set; }

    public virtual Adult Adult { get; set; }
}

public class Adult : Person
{
    public string DriversLicense { get; set; }
    public string StateIssued { get; set; }        
    public string AutoInsuranceCarrier { get; set; }
    public string PolicyNumer { get; set; }

    public string MaritalStatus { get; set; }

    //foreign key
    public int VehicleId { get; set; }
    public virtual Vehicle Vehicle { get; set; }
}

public class Address
{
    public int AddressId { get; set; }
    public int PersonId { get; set; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }

    public virtual Person Person { get; set; }
}

我陷入的逻辑模式是兄弟姐妹将拥有相同的 AddressId。当我申请离婚的 parents 时失败了,每个人的地址都有一个 child。就邮寄而言,它会起作用,因为它们位于不同的地址。感觉不是最好的设计。如果这由 UI 处理,那么它将起作用。

我的下一个想法是创建一个家庭 class 并将每个家庭成员添加到其中。在这种情况下,用户必须选择哪些人住在哪个地址。

public class Family
{
    public int FamilyId { get; set; }
    public int AddressId { get; set; }
    public List<Person> Person;
}

这似乎也不是最佳解决方案。我觉得有更好的设计。就是我自己找不到。

其中一种方法是否存在我尚未发现的缺陷? 有人可以指出我更好的方向吗?并解释为什么那个方向更好?

提前感谢您的所有见解!

"Father"、"Youth"、"Brother"等……不是人的属性,而是人与人之间关系的属性。一个人可以同时是"Father"和"Brother"和"Uncle"。

更好的设计是这样的(我不知道你的所有要求):

public class Person {
    public Name{get;set;}
    // etc...
    public List<Relationship> Relationships{get;set;}
}

public class Relationship {
    public Person P1{get;set;}
    public Person P2{get;set;}
    public RelationshipKind Kind{get;set;}
}

public class RelationshipKind {
   // for example: Father
   public Name1 {get;set;}
   // for example: Child
   public Name2 {get;set;}
}

通常您希望让您的模型像您想象的那样流畅。

例如,我不会有包含人物的地址 class。我将有一个地址 class 只包含有关地址的基本数据。亲自,我会有一个地址。这符合 "Person lives at this address" 并且可能会解决您的住所问题。这是 "Vehicle"

的设置类型

在不详细介绍整个设计的情况下,我将只关注地址问题。

我建议您将地址 class 定义为没有导航 属性 返回给某人的方式:

public class Address
{
    public int AddressId { get; set; }    

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }

}

然后我会 link 你的 Adult(甚至 Person)class 到这样的地址:

public class Adult : Person
{
    public string DriversLicense { get; set; }
    public string StateIssued { get; set; }        
    public string AutoInsuranceCarrier { get; set; }
    public string PolicyNumer { get; set; }

    public string MaritalStatus { get; set; }

    //foreign key
    public int VehicleId { get; set; }
    public virtual Vehicle Vehicle { get; set; }

    public int AddressId {get; set;}
    public virtual Address Address { get; set; }
}

使用这种方法,如果 parents 没有离婚,他们可以共享同一个地址实例。如果他们离婚了,您的申请必须为 parents 之一设置不同的地址。如果你需要找到住在同一地址的人,你可以这样做:

_dbContext.Persons.Where(p => p.AddressId = addressId) ...

如果您有 table 个州,那么您可以在很多地方使用它:DriversLicenseState、AddressState、InsuranceState 等。如果这不是空字符串,则您不必验证用户输入并可以在应用程序上放置 drop-down。

String 当前年级。如果您改为输入 child 进入一年级的年份,那么您不必每年手动更新它;它可以计算 - 尽管您还必须为 NumberOfYearsHeldBack 包含一个 int。但是,与每年更新每个学生相比,每隔一段时间更新一次 int 的工作量更少。

个人偏好:我喜欢 'NameLast' 和 'NameFirst' 而不是 'FirstName' 和 'LastName' 只是因为这意味着这些属性将在所有 IDE 下拉列表等,就像 AddressID、Address1 和 Address2

您可以考虑将 'Mother' 设为可为 null 的 'Mother?',将 'Father' 设为 'Father?' 也是如此。有些孩子根本没有两者 parents。如果你想在政治上正确,你可以考虑 'Parent1?' 和 'Parent2' 并枚举与 select 母亲、父亲、监护人的关系,因为有些孩子有 2 个妈妈或 2 个爸爸或他们的哥哥是他们的法定监护人。

在您的地址 class 中,为什么您已经有了 PersonID 属性 而还有一个人 属性?就此而言,为什么该地址根本没有 personID?这只需要 one-way。人有地址,地址没有人。这样你就可以让 5 个人都使用相同的地址。如果你试图让两者保持同步 two-way ,它就会出错,更不用说你必须在地址中有一个 personID 的 List<> 。由于地址是一种类型,因此为每个人添加另一个类型,这样您就有了 AddressPhysical 和 AddressMailing。现在你可以有 4 个孩子,每个孩子都有不同的睡觉地方,但他们都在奶奶家收到邮件 P.O.Box。

我不会在 child 中添加第三个成年人作为他们的 ICE。相反,我会制作一个成人列表<>(它实际上只是一个 ID 整数列表)这样你就可以在紧急情况下继续在列表中工作,直到你找到某人。