Как иметь несколько делегатов для объекта, не давая объекту слишком много знаний предметной области? - PullRequest
0 голосов
/ 30 июля 2010

Настройка: у меня есть одноэлементный объект диспетчера доступа к данным, назовите его Manager. У меня также есть некоторые контроллеры вида, называю их яблоками и апельсинами. Как яблоки, так и апельсины используют диспетчер для некоторых общих моделей данных / функций доступа.

Я бы хотел, чтобы менеджер перезвонил одному из них в некоторых случаях в соответствии с чем-то вроде этого:

if (someCondition)
    [self.applesDelegate callSomething];
else if (otherCondition)
    [self.orangesDelegate callSomething];

Я вижу три способа реализации этого, ни один из которых меня не устраивает.

1) делайте точно так же, как я делал выше, присвойте менеджеру некоторые свойства, такие как appleDelegate и orangesDelegate, и для этого зарегистрируйте соответствующие контроллеры представления. Но это было бы плохо, потому что у менеджера было бы знание предметной области, а я этого не хочу. Менеджер не должен ничего знать об объектах Apple или Orange.

2) иметь динамическую карту делегатов. Менеджер будет иметь некоторый NSMutableDictionary для делегатов, а яблоки и апельсины будут делать что-то вроде

[manager.delegateMap setObject:self forKey:@"applesDelegate"];

И менеджер, когда ему нужно будет вызвать делегатов, сделает что-то вроде

if (someCondition) {
    [[delegatemap objectForKey:@"applesDelegate"] callSomeMethod];
}

Это звучит работоспособно, но странно. И я не уверен, как это будет работать с обычным требованием dealloc установки делегата равным nil, если у вас нет свойства делегата, но с этим типом косвенного обращения.

3) полностью отказаться от идеи делегатов и использовать вместо этого уведомления. Менеджер будет просто генерировать уведомления, а яблоки и апельсины будут их слушать. Это приводит к потере большого количества проверок во время компиляции, поэтому я все еще думаю о делегатах, которые имеют более жесткую связь.

Какую из трех вы бы порекомендовали здесь? Или, может быть, что-то другое?

1 Ответ

1 голос
/ 30 июля 2010

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

       if ( ! apple.doItIfYouCan(condition, methodName) )
       else ( orange.doItIfYouCan(condition, methodName)

Я редко чувствую себя комфортно с таким распределением ответственности между делегатами.

Так что я бы обычно искал что-то похожее на ваш вариант 2. По сути, вы строите таблицу диспетчеризации. Во всех возможных случаях я попытался бы преобразовать условия во что-то, что можно найти в таблице. Таким образом, в действительности мы берем некоторую информацию и возвращаем объект и метод

        whatToDo = lookup(condition definition)

        whatToDo[who].what

(извиняюсь за отсутствие синтаксиса, я не говорю на вашем языке, я надеюсь, что концепции переведут - я мог бы сделать это в JavaScript, или с помощью указателей на функции в C, или в Java).

...