OOP设计:如何对一家公司进行建模,该公司可以是债务人、债权人、领导者还是只是一种关系?

发布于 2024-12-15 08:25:46 字数 414 浏览 2 评论 0原文

我正在尝试想出一种在新项目中对公司对象进行建模的好方法。其上的公司已经拥有大量数据:办公地址、电话号码、电子邮件地址、员工(也有多个角色:项目成员、销售代表等)等等。现在,就关系而言,一家公司可以与另一家公司开展业务。通常一家公司会向另一家公司购买或出售产品。但这也可能是一种双向情况,即两家公司相互买卖。我想在可以处理这些情况的模型中对这些关系进行建模。除此之外,我需要能够将公司添加到我的管理中,而我还没有与之开展任何业务,只是建立了关系。我还不想填写所有债务人详细信息,或向他们提供债务人号码。在成为债务人之前,将首先成为主导者。我不想丢失课程,因为我不想复制所有数据。例如,如果我开始从另一家公司销售或购买,人员和联系信息不会改变。

我的问题是:我如何为公司建模,以便他们可以担任多个角色? 一些伪代码或类图会很好!

预先感谢您在路上试图帮助我。

问候,特德

I am trying to think of a good way to model the company objects in a new project. A company on it's on already has a lot of data: office address(es), telephone numbers, email addresses, employees (which also have multiple roles: project member, sales representative, etc) and you name it. Now, when it comes to relationships, a company can do business with another company. Often a company buys or sells to another company. But it can also be a two-way situation in which both companies buy and sell from and to eachother. I want to model these relationships in a model which can handle these situations. Besides that, I have a need to be able to add companies to my administration which I haven't done any business with yet, just a relationship. I don't want to fill in all the debtor details yet, or give them a debtor number. Before the become a debtor, the will become a lead first. I don't want lose classes, because I don't want to replicate all the data. Personel and Contactinformation for instance does not change if I start selling or buying from another company.

My question is: how can I model company so they can have multiple roles?
Some pseudo code or class diagram would be nice!

Thanks in advance for trying to help me on my way.

Regards, Ted

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

彡翼 2024-12-22 08:25:46

有很多方法可以为这只特定的猫剥皮,并且提出建议确实需要详细了解系统的要求以及足够的时间来考虑选项。但是,假设无法导出这些关系(请参阅最后一段),我也许会考虑以下内容:-

public class Company
{
    public string Name { get; set; }        
    public IEnumerable<Relationship>
    {
        get { ... }
    }
}

public class Relationship
{
    public RelationshipType { get; set; }
    public Company { get; set; }
}

public enum RelationshipType
{
    Other,
    Debtor,
    Creditor,
    Lead,
}

假设关系之间的差异就您的 OO 模型而言是微不足道的。但是,如果您需要特定于该类型的关系的行为,那么我会考虑子类型,例如: -

public class Relationship
{
    public Company { get; set; }
    public virtual void Foo()
    {
        ....
    }
}

public class Debtor : Relationship
{
    public override void Foo()
    {
        ....
    }
}

public class Creditor : Relationship
{
    public override void Foo()
    {
        ....
    }
}

public class Lead : Relationship
{
    public override void Foo()
    {
        ....
    }
}

另一件需要考虑的事情是,这些关系最终是公司之间互动的派生。例如,当且仅当 X 公司欠 Y 公司钱时,X 公司才是 Y 公司的债务人。您的系统中是否包含此信息?如果是这样,您真的想要对该信息进行非规范化,还是动态导出该信息会更好?如果此信息在您的系统外部,并且您的系统专门设计用于保存这些事实的非规范化,那么您可以忽略本段。

There are many ways to skin this particular cat and making a recommendation really requires access to the requirements of your system in detail plus enough time to consider the options. However, assuming that these relationships cannot be derived (see last paragraph), I would, perhaps, consider something like the following:-

public class Company
{
    public string Name { get; set; }        
    public IEnumerable<Relationship>
    {
        get { ... }
    }
}

public class Relationship
{
    public RelationshipType { get; set; }
    public Company { get; set; }
}

public enum RelationshipType
{
    Other,
    Debtor,
    Creditor,
    Lead,
}

This is assuming that the differences between the relationships are trivial as far as your OO model is concerned. If, however, you require behaviors from your relationships specific to the type, then I would consider subtyping, e.g.:-

public class Relationship
{
    public Company { get; set; }
    public virtual void Foo()
    {
        ....
    }
}

public class Debtor : Relationship
{
    public override void Foo()
    {
        ....
    }
}

public class Creditor : Relationship
{
    public override void Foo()
    {
        ....
    }
}

public class Lead : Relationship
{
    public override void Foo()
    {
        ....
    }
}

Another thing to consider is that these relationships are, ultimately, derivations of interactions between the companies. E.g. a company X is a debtor of company Y if and only if company X owes money to company Y. Is this information contained in your system? If so, do you really want to de-normalize that information or would it be better to derive this on the fly? If this information is external to your system and your system is designed specifically to hold a de-normalization of these facts then you can ignore this paragraph.

一曲琵琶半遮面シ 2024-12-22 08:25:46

我认为您正在寻找AccountabilityParty 概念。当事人可以是公司,也可以是雇员。两方可以通过责任联系起来。这种责任描述了各方之间的关系类型。使用这些概念,您可以对不同类型各方之间不同类型的多个链接进行建模。

这实际上是 Fowler 在这篇关于问责制的文章中描述的分析模式。

I think you are looking for the Accountability and Party concepts. Parties can be companies, but also employees. Two parties can be linked by an accountability. This accountability describes the kind of relationship between the parties. Using these concepts, you can model multiple links of different types between parties of different types.

This actually is an analysis pattern described by Fowler in this article on accountability.

在风中等你 2024-12-22 08:25:46

如前所述,使用装饰器可以让您将一种关系“转换”为另一种关系(并在不同角色中保留同一公司的引用身份)。我建议的唯一更改是将每种类型的关系保留为自己的集合,如下所示:

public class Company
{
    public string Name { get; private set; }        
    public ISet<Debtor> Debtors { get; private set; }
    public ISet<Creditor> Creditors { get; private set; }
    public ISet<Lead> Leads { get; private set; }
    ...
}


public class CompanyRole
{
    public Company innerCompany { get; set; }

    //Override to allow equality of the same company across Roles
    public override bool Equals(object other) 
    {
       if(other is Company) 
          return ((Company) other).Name.Equals(innerCompany.Name);
       else if(other is CompanyRole) 
          return ((CompanyRole) other).innerCompany.Name.Equals(innerCompany.Name);
       else 
          return false;
    }

    public override int HashCode() 
    {
       return innerCompany.Name.HashCode();
    }
    ....
}

public class Debtor: CompanyRole 
{
    ....
}

public class Creditor: CompanyRole  
{
    ....
}

public class Lead: CompanyRole  
{
    ....
}

当您寻找特定类型的关系时,这将允许您大大简化查询,而不会因为太多类似连接的结构而疯狂,例如“...其中 myCompany.Debtors.Contains(otherCompany)...”。

Using Decorators as indicated before would allow you to "transform" a type of relationship into a different one (as well as keep the referential identity of the same company in different roles). The only change I would advise is to keep each type of Relationships as their own Collection as in:

public class Company
{
    public string Name { get; private set; }        
    public ISet<Debtor> Debtors { get; private set; }
    public ISet<Creditor> Creditors { get; private set; }
    public ISet<Lead> Leads { get; private set; }
    ...
}


public class CompanyRole
{
    public Company innerCompany { get; set; }

    //Override to allow equality of the same company across Roles
    public override bool Equals(object other) 
    {
       if(other is Company) 
          return ((Company) other).Name.Equals(innerCompany.Name);
       else if(other is CompanyRole) 
          return ((CompanyRole) other).innerCompany.Name.Equals(innerCompany.Name);
       else 
          return false;
    }

    public override int HashCode() 
    {
       return innerCompany.Name.HashCode();
    }
    ....
}

public class Debtor: CompanyRole 
{
    ....
}

public class Creditor: CompanyRole  
{
    ....
}

public class Lead: CompanyRole  
{
    ....
}

That would allow you to simplify your queries a lot when you are looking for specific types of relationships, without going crazy with too many join-like structures, e.g. '...where myCompany.Debtors.Contains(otherCompany)...'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文