Шаблон проектирования для перенаправления зависимостей - PullRequest
3 голосов
/ 23 декабря 2011

Следующая диаграмма классов - это упрощенная версия проекта, над которым я работаю.

Class Diagram

Класс A отвечает за сериализацию / десериализацию графа объектов с корнями вC. Я использую фреймворк Csharp для сериализации, поэтому, когда я десериализирую класс C, фреймворк создает новый экземпляр всего в объектах с корнем в C (это показано на диаграмме * новыми классами).Теперь я хотел бы заменить экземпляр C на C на Cnew, но проблема в том, что B1 и B2 по-прежнему указывают на старые D1 и D2.Было бы неплохо не повторять инициализацию зависимостей B2 и B2.

Я ищу способ, чтобы B1 и B2 могли иметь доступ к D1 и D2 через A, не предоставляя им доступ к C или друг другу.,Для простоты мы можем предположить, что все члены A должны быть публичными (он реализует интерфейс из используемой мной платформы, которая заставляет многих членов быть публичными).

Вот некоторые потенциальные решения, которые яхотя из:

  1. Просто прикусить пулю и заново инициализировать B1 и B2

  2. Дайте B1 и B2 ссылки на A вместо D1 и D2 ипросто игнорируйте тот факт, что это дает им доступ ко многим классам, к которым им не нужен доступ.

  3. Вместо того, чтобы давать классам B прямой доступ к классам D, имейте проход Aделегаты (указатели на функции) для функций, которые возвращают экземпляр A для D1 и D2.

  4. имеют интерфейсы A, например D1Container и D2Container, которые имеют 1 обязательный метод, который возвращает экземпляр в D1 или D2.Затем приведите A к D1Container или D2Container и передайте его B1 и B2.

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

Спасибо!

Ответы [ 2 ]

1 голос
/ 23 декабря 2011

Вы хотите ввести еще один уровень косвенности в своем дизайне: по сути, вместо сохранения ссылки на D1 и D2 вы хотите сохранить что-то, что позволило бы вам получить самые последние D1 и D2.Ваш вариант №3 (делегат) выделяется мне как самый элегантный, потому что вам не нужно вводить новые классы для реализации отложенной оценки.Все, что вам нужно - это Func<D>, который A передает B - без новых классов, интерфейсов или делегатов;все остается хорошо инкапсулированным.

class A {
    private B myB;
    private C myC;
    public A() {
        myC = new C();
        myB = new B(() => myC.MyD);
    }
}
class B {
    private readonly Func<D> getD;
    public B(Func<D> getD) {this.getD = getD;}
    public D { get { return getD(); } }
}
class C {
    public D MyD {get; private set;}
}

Теперь, если A изменит свой C или C изменит свой D, B.D продолжит возвращать правильный D автоматически.Это потому, что под капотом B хранится ссылка на A, но он понятия не имеет, что делает.

0 голосов
/ 23 декабря 2011
  1. и 2. игнорировать части того, что я прочитал, чтобы соответствовать требованиям.
  2. - проблема, если B имеет доступ к определению A и может просто отбросить A назад, передав егодоступ к C

  3. Является наиболее перспективным вариантом.Я бы реализовал это, выставляя события, которые B слушает.

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