Каков наилучший способ разделить проблемы для этого кода?
В предыдущем вопросе один из комментариев 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
не должен знать свой собственный статус вообще.