ООП дизайн: как смоделировать компанию, которая может быть должником, кредитором, лидером или это просто отношения? - PullRequest
2 голосов
/ 11 ноября 2011

Я пытаюсь придумать хороший способ моделирования объектов компании в новом проекте.Компания, в которой она работает, уже имеет много данных: адрес (а) офиса, номера телефонов, адреса электронной почты, сотрудники (которые также имеют несколько ролей: участник проекта, торговый представитель и т. Д.) И вы называете это имя.Теперь, когда дело доходит до отношений, компания может вести бизнес с другой компанией.Часто компания покупает или продает другой компании.Но это также может быть двусторонняя ситуация, когда обе компании покупают и продают друг друга.Я хочу смоделировать эти отношения в модели, которая может справиться с этими ситуациями.Кроме того, мне нужно иметь возможность добавлять компании в свою администрацию, с которыми я еще не имел никакого отношения, только отношения.Я пока не хочу заполнять все данные должника или давать им номер должника.Прежде чем стать должником, первым станет лидер.Я не хочу терять классы, потому что я не хочу копировать все данные.Персональная и контактная информация, например, не изменится, если я начну продавать или покупать у другой компании.

Мой вопрос: как я могу моделировать компанию, чтобы они могли иметь несколько ролей?Какой-нибудь псевдокод или диаграмма классов были бы хороши!

Заранее спасибо за попытку помочь мне в моем пути.

С уважением, Тед

Ответы [ 3 ]

3 голосов
/ 11 ноября 2011

Существует множество способов обрезать шкуру этой конкретной кошки, и для вынесения рекомендации действительно необходим подробный доступ к требованиям вашей системы плюс достаточно времени для рассмотрения вариантов.Однако, предполагая, что эти отношения не могут быть получены (см. Последний абзац), я бы, возможно, рассмотрел что-то вроде следующего: -

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,
}

Это предполагает, что различия между отношениями тривиальны, посколькуВаша ОО модель обеспокоена.Однако, если вам требуется поведение из ваших отношений, специфичных для данного типа, я бы рассмотрел подтип, например:компании.Например, компания X является должником компании Y тогда и только тогда, когда компания X должна деньги компании Y. Содержится ли эта информация в вашей системе?Если да, действительно ли вы хотите де-нормализовать эту информацию или было бы лучше получить ее на лету?Если эта информация является внешней по отношению к вашей системе, и ваша система специально разработана для проведения нормализации этих фактов, вы можете игнорировать этот параграф.

1 голос
/ 11 ноября 2011

Я думаю, что вы ищете понятия Accountability и Party. Сторонами могут быть компании, но и сотрудники. Две стороны могут быть связаны подотчетностью. Эта ответственность описывает вид отношений между сторонами. Используя эти концепции, вы можете моделировать несколько связей разных типов между сторонами разных типов.

На самом деле это шаблон анализа, описанный Фаулером в этой статье об ответственности .

0 голосов
/ 19 июля 2016

Использование декораторов, как указано выше, позволит вам «преобразовать» тип отношений в другой (а также сохранить ссылочную идентичность одной и той же компании в разных ролях).Единственное изменение, которое я бы посоветовал - сохранить каждый тип отношений как свою собственную коллекцию, как в:

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) ...».

...