Алтернативен модел на дизайн на Observer за .Net

Първоначално щях да внедря модел на наблюдател в C# 3.0, за да разреша проблема си, въпреки че нямаше да бъде приложен точно по същия начин.

Проблемът ми е, че имам уеб приложение с потребители, които могат да публикуват съобщения. Известията не отиват директно до други потребители, а до разпределен кеш, където статистическите обекти се актуализират и потребителите могат да проверят статистиката и да решат дали искат актуализациите или не.

В момента имам интерфейс на IObserver, който ще трябва да внедри множество метода Update() въз основа на това кой публикува съобщение и как го прави.

Разгледах също модела на посредника, но не мисля, че е подходящ, тъй като екземплярите на посредник няма да имат списък с това кой е влязъл в момента.

Сега се чудя дали има друг установен модел на проектиране, който би бил по-подходящ или трябва просто да завърша изграждането на текущия си модел на наблюдател, за да отговаря на нуждите ми.

Благодаря


person CountCet    schedule 28.07.2009    source източник
comment
Тази статия в msdn ми даде по-добра представа какво обясняват отговорите по-долу. msdn.microsoft.com/en-us/library/ms954621.aspx   -  person CountCet    schedule 28.07.2009


Отговори (3)


Не можете ли да го приложите чрез събития/делегати? Това е стандартният начин за прилагане на модела Observer в C# и други .Net езици.

person Oded    schedule 28.07.2009
comment
Събитията може да са най-ранната реализация на наблюдателя, но те са недостатъчни по много начини. Най-лошото от тях е липсата на добър механизъм за справяне с продължителността на абонамента, ако издателят или абонатът бъдат изоставени [абонаментът трябва да стане невалиден, ако издателят или абонатът бъдат изоставени]. Други модели могат да предоставят механизми за облекчаване на тези проблеми. - person supercat; 27.01.2013
comment
@supercat - През 2009 г. нямаше реактивни разширения, нямаше Obeserver/Observable в рамките на BCL и събития, ако не искахте да пуснете свои собствени. - person Oded; 27.01.2013
comment
@Oded: Честно, въпреки че навиването на собствения не беше особено трудно. Иска ми се събитията от самото начало да са били реализирани чрез метод за абониране, който връща IDisposable. Не би трябвало да има някакъв специален тип „събитие“; абонирането би било метод като всеки друг. Такъв модел би улеснил класовете да позволяват абонамент за асинхронно събитие (ако се направи опит за изхвърляне на обект в момент, когато издателят е зает, накарайте го да зададе флаг в себе си и в издателя на събития, за да каже, че се е случило ; тогава издателят би могъл... - person supercat; 28.01.2013
comment
...почисти събитието, когато му е удобно). Чудя се какви реални предимства се постигат от наличието на типа събитие като такъв? - person supercat; 28.01.2013
comment
@supercat - Нямам отговор за вас. Дизайнерите и архитектите на .NET може да имат отговор (въпреки че това може да е наследство от VB6) - person Oded; 28.01.2013
comment
@Oded: Наясно съм с нищо дори отдалечено наподобяващо .net събития във vb6. Доколкото си спомням, ако някой имаше Button с име Foo, щракването върху Foo би накарало системата да изпълни метод Foo_Click, ако съществуваше (и да не направи нищо, ако не); ако имаше масив от бутони, наречен Bar(), щракването върху който и да е ще доведе до извикване на Bar_Click, предавайки допълнителен параметър, за да посочи кой бутон. Предполагам, че много неща са свързани с факта, че делегатите и масивите са били единствените квазигенерични типове в ранните версии на .net; много грозотии произтичат от първоначалната липса на генерични лекарства. - person supercat; 28.01.2013

Не са ли .Net събитията просто маскирани модели на наблюдатели? :) Може да имате клас, да речем, Statistic, и този клас да изложи събитие OnUpdate().

person cwap    schedule 28.07.2009
comment
Това, че трябва да проверите нулата на делегата на вашето събитие, преди да го извикате, ми се струва, че сте принуден да погледнете през рамо, за да сте сигурни, че някой ви наблюдава. Което изглежда доста странно концептуално. - person xyz; 28.07.2009
comment
Съгласен, винаги съм мразил и това :) - person cwap; 28.07.2009
comment
@al7ut9ov8my4wopt5ur6ais5: Предоставянето на резервното поле за делегат на събитие се дава със същото име като на самото събитие IMHO беше голяма грешка в дизайна на C#. Подкрепеното поле трябваше да получи друго име и опитът да се използва името на събитието като извикване на метод трябва да генерира автоматично поведението изпълнение, ако не null, иначе не прави нищо; опитът за присвояване на null на името на събитието или за сравняването му с null трябваше да работи върху полето за печене. В противен случай име на събитие не трябва да се счита за синоним на делегата. - person supercat; 28.01.2013

C# е взел модел на проектиране и го е превърнал в първокласен гражданин на езика. Защо просто не използвате предоставеното? Не виждам нищо във вашия пример, което да не може да се направи с вградената структура на събития в C#.

person Ed S.    schedule 28.07.2009
comment
Не съм против използването на събития, но искам да предпазя от двупосочна зависимост между потребител и клас, която би внедрила актуализацията на статистиката. - person CountCet; 28.07.2009
comment
Няма никаква зависимост. Един клас излага събитие, друг го обработва. Моделът намалява необходимостта от свързване/зависимости между класовете. - person Ed S.; 28.07.2009
comment
@EdS.: При правилен модел на наблюдател, издателят на събитие не трябва да пречи на абоната да бъде събиран боклук (има ситуации, в които абонат на събитие може да направи нещо полезно, без да съществува никаква препратка към него; но те днес вероятно се управляват най-добре от накарайте абоната да използва ConditionalWeakTable, за да прикачи живота си към този на нещата, които може да се интересуват от него). Събитията са основен източник на изтичане на памет в .net. - person supercat; 28.01.2013
comment
@supercat: Да, аз сам поправих няколко. Въпреки това не мисля, че е толкова често срещано, тъй като повечето абонати надживяват издателя. като всяко нещо, трябва да знаеш какво правиш. Никоя абстракция не е перфектна. Както казахте обаче, слабото референтно внедряване е за предпочитане. - person Ed S.; 28.01.2013