Каковы плюсы и минусы того, что «менеджер» что-то делает с объектом или объект делает что-то сам? - PullRequest
0 голосов
/ 13 февраля 2019

Я изучал удобство добавления функциональности к объектам, которые ранее обрабатывались «менеджерами» или «контроллерами».Я просто волновался, были ли какие-то проблемы, работающие таким образом.Основная проблема, которую я вижу, это связывание.

В качестве примера, давайте использовать увольнение сотрудника из бизнеса.

Ранее я бы работал так:

class Employee
{
    // Does employee stuff
}

class Business
{
    public List<Employee> employees
}

class BusinessManagement
{
    Business buisness
    public void FireEmployee(Employee employee)
    {
        business.employees.Remove(employee);
    }
}

Сейчас я пытаюсь это сделать:

class Employee
{
    Business business
    Fire()
    {
        business.employees.Remove(this);
    }
}

class Business
{
    public List<Employee> employees
}

Последний метод хорош и удобен, потому что вам просто нужна ссылка на сотрудника, и вы можете запустить его где угодно.Вам также не нужен класс управления.

1 Ответ

0 голосов
/ 13 февраля 2019

Я думаю, вы правы, что вам не стоит связываться здесь - я считаю ваш пример плохой практикой.Но давайте распакуем и покажем способ, которым мы можем достичь того же поведения с помощью контракта между классами, который является более понятным, предсказуемым и обслуживаемым.

У бизнеса много сотрудников, он знает, кто его использует, поэтомуимеет смысл владеть коллекцией ссылок на Employee объектов.Сотрудник (для простоты) работает на один бизнес, поэтому имеет смысл для Employee содержать ссылку на Business объект.Эти ссылки не обязательно объединяют классы в отрицательном смысле, если контракты между ними явно заключаются в открытых методах для каждого объекта, вызов которого контролируется этим классом, и чья бизнес-логика является задачей этого класса.

Бизнес увольняет сотрудника, и сотрудник также должен знать, что его уволили.Если бы я собирался сделать это, я бы поместил метод Fire(Employee e) в класс Business - внутри этого метода я, скорее всего, хотел бы вызвать e.GetFired(), а затем удалить сотрудника из коллекции сотрудников.Тогда Employee.GetFired() установит для собственного свойства Business *1013* значение null.

Это может работать в обоих направлениях, сохраняя разделение между этими классами.Предположительно, сотрудник может уволиться с работы - таким образом, Employee.Quit() может вызвать Business.EmployeeHasQuit(Employee e), передавая себя в качестве ссылки, - позволяя экземпляру Business взять на себя ответственность за удаление экземпляра Employee из коллекции.

Ваш пример является примером связывания, потому что метод класса Employee 'GetFired() использовал его ссылку на бизнес-объект для доступа к общедоступной коллекции и самому ее удалению.Также было бы соединение, если Business.Fire(Employee e) метод установлен e.Business = null.Это разумное правило: классы не должны напрямую изменять членов других классов;позволяя каждому классу управлять своим собственным состоянием, вы можете реализовать поведения, чтобы гарантировать, что вещи всегда находятся в допустимом состоянии, и запускать другие необходимые поведения (например, мы хотим убедиться, что при выходе сотрудника их проход безопасности отменяется, и этоможет произойти внутри EmployeeHasQuit() - если сотрудник только что удалил себя из коллекции Business, это не имело бы место. Компания также может захотеть поместить сотрудника, который уволился или был уволен, в коллекцию прежних сотрудниковследите за ними позже.

Надеюсь, это послужит легко усваиваемым примером того, как объекты могут общаться друг с другом, сохраняя при этом полную ответственность за свои состояния и поведение!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...