Делегатлардан “манбаа-кузатувчи “ типидаги объектлар ўртасидаги алоқани таъминлаш мақсадида фойдаланишни кўрайлик. Системани биргаликда ишловчи бир нечта тўпламларга тақсимлаш натижасида ўзаро боғланган объектлар ўртасидаги мосликни қўллаб – қувватлашга тўғри келади. Бунда классларни қатъий равишда боғлашдан қочиш мақсадга мувофиқ бўлади, чунки бу холат кодлардан кўп марта фойдаланиш м масаласига салбий таъсир кўрсатади.
Дастурнинг бажарилиши жараёнида объектлар ўртасидаги алоҳани таъминлаш учун қуйидаги стратегия қўлланилади. Манбаа деб аталадиган объект бошқа объектларнинг манфаатларини ифодалайдиган холатлари ўзгарганда, уларга бу ҳақида ахборот жўнатади. Бу объектлар кузатувчи деб аталади. Ахборот олганидан кейин, кузатувчи манбаадан ўз холатини синхронлашини сўрайди. Бундай стратегияга мисол қилиб электрон жадваллар ва улар асосида қурилган диаграммалар ўртасидаги боғланишни олиш мумкин.
Дастурчилар кўпинча объектлар ўртасидаги алоҳа хамда ўзаро боғланишни ташкил қилиш бир хил схемасидан турли мақсадларда фойдаланадилар. Бундай схемаларни паттернлар ёки лойиҳалаш шаблонлари деб аталади. Тавсифланган стратегия “кузувчи” деган паттерн номи билан машҳур.
Кузатувчи (observer) объектлар ўртасидаги “ бирга кўп” типидаги боғланишларни белгилаб беради. Шунинг учун бундай объектнинг холати ўзгарганда у билан боғлиқ бўлган барча объектлар бу ҳақда огоҳлантирилади ва шунга мос равишда тўғридан – тўғри янгиланади. 17.2-листингда келтирилган намунада учта кузатувчини огохлантириш схемаси намойиш қилинган. Объект холатининг гипотетик ўзгариши “Ой” деган маълумот билан моделлаштирилоади. Методлардан бири кўргазмалилик учун статик қилиб яратилган.
25.2-листинг. Делегат ёрдамида кузатувчиларни огохлантириш
using System; namespace ConsoleApplication1 { public delegate void Del( object o ); // делегат эълн қилинмоқда class Subj // манбаа-класс { Del dels; // делегат экземпляри эълон қилинмоқда public void Register( Del d ) // делегатни қайд қилиш { dels += d; } public void OOPS() // нимадир содир бўлди { Console.WriteLine( "ОЙ!" ); if ( dels != null ) dels( this ); // кузатувчилар огохлантирилмоқда } } class ObsA // Класс-Кузатувчи { public void Do( object o ) // Манбаадаги ходисага реакция { Console.WriteLine( "Бечора!" ); } } class ObsB // Класс-Кузатувчи { public static void See( object o ) // Манбаадаги ходисага реакция { Console.WriteLine( "Ха бу арзимаган гап!" ); } } class Class1 { static void Main() { Subj s = new Subj(); // класс-манбаа объекти ObsA o1 = new ObsA(); // кузатувчи класс объектлари ObsA o2 = new ObsA(); // кузатувчи класс объектлари s.Register( new Del( o1.Do ) ); // методларни қайд қилиш s.Register( new Del( o2.Do ) ); // манбаадаги кузатувчилар s.Register( new Del( ObsB.See ) ); // ( делегат экземплярлари ) s.OOPS(); // ходисаларни юзага келтириш } } } Манбаада делегат экземпляри эълон қилинмоқда ва бу экземплярга манбаа холатининг ўзгариши ҳақида огохлантириш олишни хохлаган объектларнинг методлари киритилади. Бу жаарённи делегатларни қайд қииш деб аталади. Қайд қилишда метод номи рўйхатга киритилади. “Х соати” етиб келганда қайд қилинган барча методлар навбати билан делегат орқали чақирилади.
Юқоридаги дастурнинг натижаси:
ОЙ!
Бечора!
Бечора!
Ха бу арзимаган гап!
Кузатувчи ва манбаа ўртасидаги тескари алоҳани таъминлаш учун делегат object типидаги параметр билан эълон қилинган. Бунда чақирилувчи методга чақирувчи объектга ҳавола узатилади. Демак, чақирилаётган метод чақирувчи объект холати ҳақидаги огохлантиришни олиши мумкин.
Дастур бажарилаётган вақтда "манбаа — кузатувчи" боғланмаси ҳар бир объект учун алоҳида ўрнатилади. Агар Кузатувчи манбаадан бошқа огохлантиришлар олишни хохламаса, у холда унга мос методни делегат рўйхатидан Remove методи ёрдамида ўчириш мумкин, масалан:
public void UnRegister( Del d ) // делегатни ўчириш { dels -= d; }