Каков наилучший способ разделить проблемы для этого кода?

В предыдущем вопросе один из комментариев Dr Herbie о принятом ответе состоял в том, что мой метод выполнял две обязанности: изменение данных и сохранение данных.

То, что я пытаюсь выяснить, - лучший способ отделить эти проблемы в моей ситуации.

Продолжая с моим примером наличия объекта Policy, который получен через NHibernate....

В настоящее время я устанавливаю политику неактивной:

Policy policy = new Policy();
policy.Status = Active;

policyManager.Inactivate(policy);

//method in PolicyManager which has data access and update responsibility
public void Inactivate(Policy policy)
{
    policy.Status = Inactive;
    Update(policy);
}

Если бы я должен был разделить ответственность за доступ к данным и обновление данных, что было бы лучшим способом сделать это?

Лучше ли, чтобы PolicyManager (который действует как шлюз для дао) управлял состоянием объекта Policy:

Policy policy = new Policy();
policy.Status = Active;

policyManager.Inactivate(policy);
policyManager.Update(policy);

//method in PolicyManager
public void Inactivate(Policy policy)
{
    policy.Status = Inactive;
}

Или чтобы объект Policy поддерживал свое собственное состояние и затем использовал класс manager для сохранения информации в базе данных:

Policy policy = new Policy();
policy.Status = Active;

policy.Inactivate();

policyManager.Update(policy);

//method in Policy
public void Inactivate()
{
    this.Status = Inactive;
}

4 ответа

Решение

Как продолжение моего первоначального комментария:) ... На данный момент ваша лучшая ставка - это третий вариант, но если все усложняется, вы можете пойти со вторым, добавив методы фасада для выполнения предварительно определенных последовательностей:

Policy policy = new Policy();

policy.Status = Active;

policyManager.InactivateAndUpdate(policy);


//methods in PolicyManager
public void Inactivate(Policy policy)
{
    // possibly complex checks and validations might be put there in the future? ...
    policy.Status = Inactive;
}

public void InactivateAndUpdate(Policy policy)
{
    Inactivate(policy);
    Update(policy);
}

InactivateAndUpdate - это своего рода метод фасада, который просто делает вызывающий код немного более аккуратным, в то же время позволяя методам, выполняющим реальную работу, разделять задачи (что-то вроде разрыва единой ответственности за методы, но иногда вам просто нужно будь прагматичным!) Я намеренно называю такие методы в стиле Xи Y, чтобы они выделялись как выполняющие две вещи.

Затем метод InactivateAndUpdate освобождает вас от необходимости начинать реализацию шаблонов стратегий или разделять фактические методы реализации в качестве объектов команд для динамической обработки или любой другой архитектуры, которая может стать возможной в будущем.

Что бы я сделал:

  • Создайте репозиторий, который сохраняет и получает Политики. (PolicyRepository)

  • Если у вас есть сложная логика, которую необходимо выполнить для активации / деактивации политики, вы можете создать для этого Сервис. Если этой службе требуется доступ к базе данных, вы можете при необходимости передать ей PolicyRepository. Если никакой сложной логики не используется, и активация / деактивация политики - это просто вопрос установки флага в false или true, или если участвуют только члены класса политики, то почему "Активировано" не является простым свойством политики класс, который вы можете установить в false / true? Я хотел бы создать службу, только если задействованы другие объекты или если для активации или деактивации политики требуется доступ к БД.

Я определенно выбрал бы третий вариант по причинам, которые вы упомянули:

объект Policy поддерживает свое собственное состояние, а затем использует класс manager для сохранения информации в базе данных

Также взгляните на шаблон репозитория. Это может заменить ваш PolicyManager,

Если статус является частью состояния Policy класс, то Policy также должен иметь Inactivate метод - это просто базовая инкапсуляция. Запутывание нескольких классов в одну ответственность, по меньшей мере, так же плохо, как и предоставление одному классу нескольких обязанностей.

В качестве альтернативы, статус может рассматриваться как метаданные о Policyпринадлежащих не к Policy но к PolicyManager, В этом случае, тем не менее, Policy не должен знать свой собственный статус вообще.

Другие вопросы по тегам