Хорошо, в LoD нет ничего особенно плохого в передаче объекта реализации, «плагина» в конструкторе. Что важно, так это то, что интерфейс класса мало что говорит вам о этой реализации.
Если ваш интерфейс к WebGetTask зависит от точной реализации HttpService, , что нарушает закон Деметры.
Хитрость в том, чтобы подумать о сигнатуре интерфейса WebGetTask. Само название говорит о том, что вы не совсем следуете Закону Деметры - или принципу наименьшего знания - потому что вы определяете класс, который (1) определен как специфичный для сети, а (2) вместо этого глагол существительного.
Теперь, ни то, ни другое не обязательно является неправильным, но оба они, если хотите, являются "ОУ-запахами", признаками того, что вы, возможно, не думаете достаточно объектно.
Итак, давайте попробуем «рефакторинг» дизайна. Во-первых, подумайте о GetTask, который не имеет связанной с ним «сети». Затем вы можете либо во время конструирования, либо в более позднее время создать сервисный объект и передать его внутрь. Если это HttpService, это нормально, но пользователю вашего класса не нужна информация о том, что находится под прикрытием.
Второе, давайте сделаем это существительным. Назовите это TaskFactory - ваша интуиция привела вас прямо туда - с помощью ctor, который использует IOService, который я только что изобрел как абстрактный интерфейс, реализованный HttpService.
Теперь у вас есть (это своего рода псевдокод Java / C ++, не волнуйтесь о деталях синтаксиса):
class Task { ... }
class TaskFactory {
public TaskFactory(IOServer svc){...}
public Task get(){...}
}
и вы используете его, написав
TaskFactory fac = new TaskFactory(new HttpService());
Task tsk = fac.get();
Теперь мы понимаем минимум внутренних функций TaskFactory, службы ввода-вывода и, в этом отношении, задач.