Почему в Presenter First метод SubscribeSomeEvent в интерфейсе предпочтительнее простых старых событий?

Недавно я узнал о Presenter First и прочитал их технические документы, блоги и т. Д.

В большинстве примеров, которые я нашел, события объявляются не непосредственно в интерфейсе, а как метод для него. Например,

public interface IPuzzleView
{
    void SubscribeMoveRequest(PointDelegate listener);
    // vs
    event PointDelegate MoveRequest;
}

Я не совсем понимаю, почему. Я думал, что где-то видел статью / статью / блог, где объясняются причины этого, но я больше не могу его найти. В указанном тексте также содержались фрагменты кода модульного тестирования - я знаю это, потому что помню, как говорил себе, что один из модульных тестов был неверным.

ОБНОВИТЬ:

Ниже приведен пример для сравнения:

public class Collect
{
    public static CollectAction<T> Argument<T>(int index,
        CollectAction<T>.Collect collectDelegate)
    {
        CollectAction<T> collect = new CollectAction<T>(index, collectDelegate);
        return collect;
    }
}

public interface IApplicationView
{
    event EventHandler Load;

    // or

    void SubscribeLoad(Action action);
}

Mockery mockery = new Mockery();
IApplicationView view = mockery.NewMock<IApplicationView>();
IApplicationModel model = mockery.NewMock<IApplicationModel>();

Стиль подписки:

Action savedAction = null;
Expect.Once.On(view).Method("SubscribeLoad").Will(
    Collect.Argument<Action>(0,
    delegate(Action action) { savedAction = action; }));
Expect.Once.On(model).Method("LoadModules");
new ApplicationPresenter(view, model);
savedAction();
mockery.VerifyAllExpectationsHaveBeenMet();

против события:

Expect.Once.On(view).EventAdd("Load", Is.Anything);
Expect.Once.On(model).Method("LoadModules");
new ApplicationPresenter(view, model);
Fire.Event("Load").On(view);
mockery.VerifyAllExpectationsHaveBeenMet();

К вашему сведению, описанный выше стиль событий не будет работать как есть, так как ApplicationPresenter сразу же собирает мусор, а проводка никогда не происходит.

1 ответ

Решение

Короткий ответ таков: Presenter First изначально развивался во времена.NET 1.1 и VS2003, и события C# могли быть проблематичными.

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

В опубликованных примерах мы хотели не связывать метод Presenter First с языковой функцией. (Например, Java не имеет эквивалента C# событий или делегатов, но это не значит, что вы не можете использовать шаблон Observer.)

Я вижу, что события, анонимные делегаты и насмешливые инструменты прошли долгий путь за последние несколько лет. В следующий раз, когда я возьму проект на C#, я пересмотрю все свои предположения о "наилучшем способе" обработки подписки и отправки событий. Приведенные выше примеры интригуют.

Подводя итог нашим оригинальным, возможно, датированным причинам скрытия нашего использования событий C#: - подписка на поддельные события была невозможна в модульных тестах - иногда мы использовали другой внутренний механизм для обработки подписки / отправки событий. Это привело к несогласованности между интерфейсами. - Несколько раз мы рассматривали возможность отказа от событий C# даже внутри компании, поскольку они вели себя по-разному, когда не было подписчиков. Разоблачение событий извне усложнило бы повторную реализацию.

Когда Джихо Хан связал меня с этим вопросом, он также спросил о привязке данных и более конкретном примере PF, на который я ответил, опубликовав новый, более полный пример Presenter First и подробно остановившись на адаптерах.

Другие вопросы по тегам