Шаблон дизайна: какой выбрать? - PullRequest
6 голосов
/ 28 сентября 2010

Прежде всего, это всего лишь концепция, у меня пока нет фактического программирования. Это ситуация:

У меня есть класс A, который использует Файловую систему для отслеживания изменений в папке. (используя события)

Тогда у меня есть «Класс коллекции» B, в котором есть список А.

Теперь я хочу, чтобы произошло следующее:

Изменение происходит с папкой, A обнаруживает это и отправляет сообщение B, B передает это сообщение в класс C. Затем класс C запускает метод, который обновляет GUI. (Какие изменения были внесены и т.д ..)

Теперь я долго обдумывал эту тему, но не могу найти решение. Но я нашел 2 шаблона проектирования:

Посредник и Наблюдатель.

Как инженер-программист, я в какой-то степени создал шаблон Observer, поэтому я знаком с некоторыми основами.

Теперь на мои вопросы:

  • Какой шаблон лучше всего использовать в этой ситуации?

  • Как мне сделать так, чтобы B передавал сообщение C?

  • Нужны ли мне специальные события / делегаты, чтобы заставить А передавать данные в В или я могу использовать встроенные события?

P.S .: Я использую C # в качестве языка программирования.

edit: Спасибо всем за помощь, голоса в пути.

Ответы [ 5 ]

5 голосов
/ 28 сентября 2010

Наблюдатель в порядке. Вы можете либо сделать C наблюдателем B (чтобы B передавал события от A к C), либо заставить C слушать напрямую A (вероятно, это худший выбор, поскольку он создает прямую зависимость от C до A).

Обратите внимание, что это в основном разновидность Model-View-Controller , где A - модели, а C - вид. Теперь, будет ли B делать надлежащий контроллер, во многом зависит от его обязанностей: если это всего лишь набор из A, не очень хорошая идея сделать его контроллером. Без подробностей о ваших занятиях и обязанностях сложно сказать больше.

4 голосов
/ 28 сентября 2010

Из того, что я извлек из этого, есть группа объектов "A", которые асинхронно передают события одному B, который, в свою очередь, передает эту информацию одному C.

Итак,пусть B содержит и наблюдает за A, и пусть C наблюдает за B.

Если у вас много A, вы, возможно, захотите, чтобы B проводил сбор / кэширование событий A, прежде чем уведомлять C. Особенно, если C обслуживаетпользовательский интерфейс.

Дополнительное примечание : не чрезмерно шаблонизируйте ваше программное обеспечение.Старайтесь быть непредубежденными и всегда находите самое простое и простое решение.Используйте шаблон там, где это уместно, и не только потому, что это возможно.Я видел много людей, которые добавляли прокси, шаблоны команд, наблюдателей, MVC, посредников и т. Д., Где они были ненужными.

Удачи.

3 голосов
/ 28 сентября 2010
public class A
{
    public event FileSystemEventHandler FileSystemEvent;

    A()
    {
        this.fsw = new FileSystemWatcher();
        this.fsw.OnFileSystemEvent += (sender, e) => 
            { if(this.FileSystemEvent != null) 
                 this.FileSystemEvent(this,e); };
    }
}

public class B
{
    public event FileSystemEventHandler FileSystemEvent;

    B()
    {
        this.RegisterAClasses();
        foreach( A item in this.AClasses )
             item.FileSystemEvent += (sender, e) =>
                 { if(this.FileSystemEvent != null) 
                      this.FileSystemEvent(sender, e) };
    }
}

public class C
{
    C()
    {
        this.RegisterBClass();
        this.BClass.FileSystemEvent += (sender, e) => 
             { /* update gui... */ };
    }
}

(код псевдо ...)

1 голос
/ 28 сентября 2010

В итоге я использовал почти тот же сценарий для демонстрации Reactive Extensions.

RX - это формализм шаблона наблюдателя, но обобщенный, чтобы быть обратным / двойным к шаблону итератора.

Подробности и исходный код - http://code.msdn.microsoft.com/RxDemos

0 голосов
/ 28 сентября 2010

Наблюдатель - правильная модель здесь. Я не понимаю, почему ты сказал это:

Тогда у меня есть «Класс коллекции» B который имеет список А.

потому что, согласно шаблону Observer, я думаю, что B должен соблюдать A, поэтому в классе A есть несколько B для прослушивания события, инициируемого A (папка должна быть изменена). Точно так же класс C должен соблюдать B, поэтому в классе B есть несколько объектов C, которые регистрируются для прослушивания события, инициируемого B. Необходимость для пользовательского события или встроенного события зависит от вашего класса. Если это класс .NET, я думаю, что есть какое-то событие для уведомления об изменении в директории. Если нет, вы должны написать свои собственные события / делегат.

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