Ekspeditorlik (ob'ektga yo'naltirilgan dasturlash) - Forwarding (object-oriented programming)

Yilda ob'ektga yo'naltirilgan dasturlash, ekspeditorlik degan ma'noni anglatadi ob'ekt (yoki a mulk yoki a usul ) aslida boshqa ob'ektning tegishli a'zosidan foydalanishga olib keladi: use is uzatildi boshqa ob'ektga. Ekspeditorlik qatorida ishlatiladi dizayn naqshlari, bu erda ba'zi a'zolar boshqa ob'ektga yo'naltiriladi, boshqalari esa to'g'ridan-to'g'ri ishlatiladigan ob'ekt tomonidan boshqariladi. Ekspeditorlik ob'ekti tez-tez a deb nomlanadi o'rash ob'ekti, va aniq yo'naltiruvchi a'zolar deyiladi o'rash funktsiyalari.

Delegatsiya

Ekspeditorlik ko'pincha aralashtiriladi delegatsiya; rasmiy ravishda ular bir-birini to'ldiruvchi tushunchalardir. Ikkala holatda ham ikkita ob'ekt mavjud va birinchi (jo'natuvchi, o'ralgan) ob'ekt ikkinchi (qabul qiluvchi, o'ralgan) ob'ektdan foydalanadi, masalan, usulni chaqirish uchun. Ular nimada farq qiladilar o'zini o'zi qabul qiluvchi ob'ektga ishora qiladi (rasmiy ravishda, ichida baholash muhiti qabul qiluvchi ob'ekt bo'yicha usul): topshirishda u jo'natuvchi ob'ektni, ekspeditsiyada esa qabul qiluvchi ob'ektni anglatadi. Yozib oling o'zini o'zi qismi sifatida yashirin ravishda ishlatiladi dinamik jo'natish (usulning aniqligi: usul nomi qaysi funktsiyani anglatadi).

Ekspeditorlik va topshirish o'rtasidagi farq - bu o'z-o'zidan parametrni o'rash orqali qo'ng'iroq qilishda. Delegatsiya bilan self parametri o'rash bilan bog'lanadi, yo'naltirish bilan u o'rash bilan bog'lanadi. ... Ekspeditorlik - bu avtomatik xabarni qayta yuborish shakli; delegatsiya - bu "normal" meros kabi kompilyatsiya / bog'lanish vaqtida emas, balki ish vaqtida ota-onaning (superklass) majburiyligi bilan merosning shakli.[1]

Masalan, quyidagi kod berilgan:

// Yuboruvchibekor n() {  chop etish("n1");}// qabul qiluvchibekor m() {  chop etish("m2"); n();}bekor n() {  chop etish("n2");}

delegatsiya ostida bu chiqadi m2, n1 chunki n () asl (jo'natuvchi) ob'ekt kontekstida baholanadi, yo'naltirish ostida esa bu chiqadi m2, n2 chunki n () qabul qiluvchi ob'ekt kontekstida baholanadi.[1]

Oddiy foydalanishda ekspeditsiya ko'pincha "delegatsiya" deb nomlanadi yoki delegatsiya shakli deb hisoblanadi, ammo ehtiyotkorlik bilan foydalanishda ular aniq nima bilan ajralib turadi o'zini o'zi ga tegishli. Delegatsiya o'xshashdir meros olish, xatti-harakatlarni qayta ishlatishga imkon beradi (va aniq) kodni qayta ishlatish ) holda o'zgaruvchan baholash konteksti, yo'naltirish shunga o'xshash tarkibi, chunki ijro faqat qabul qiluvchi (a'zo) ob'ektga bog'liq, emas (asl) yuboruvchi ob'ekt. Ikkala holatda ham qayta ishlatish dinamik, ya'ni ishlash vaqtida aniqlanadi (. Asosida ob'ekt statik emas, balki kompilyatsiya / bog'lash vaqtida aniqlangan ma'noga ega emas, balki foydalanishga topshirilgan yoki yo'naltirilgan) sinf dan meros qilib olingan). Meros singari, delegatsiya ham yuboruvchi ob'ektga asl xatti-harakatlarini o'zgartirishga imkon beradi, ammo shunga o'xshash muammolarga moyil bo'ladi. mo'rt asosiy sinf; ekspeditsiya yanada kuchli inkassulyatsiyani ta'minlaydi va bu muammolarning oldini oladi; qarang meros ustida tarkibi.[1]

Misollar

Java-da aniq yo'naltirishning oddiy misoli: ning misoli B qo'ng'iroqlarni oldinga yo'naltiradi foo uning usuli a maydon:

sinf B {    A a;    T foo() { qaytish a.foo(); }}

Amalga oshirishda e'tibor bering a.foo (), bu ob'ekt a (pastki turi A), asl ob'ekt emas (masalan B). Bundan tashqari, a ning misoli bo'lishi shart emas A: bu subtipning bir misoli bo'lishi mumkin. Haqiqatdan ham, A sinf ham bo'lishi shart emas: bu interfeys bo'lishi mumkin /protokol.

Meros bilan qarama-qarshilik foo superklassda aniqlanadi A (bu interfeys emas, balki sinf bo'lishi kerak) va subklassning misoli chaqirilganda B, unda belgilangan koddan foydalaniladi A, lekin bu ob'ekt hali ham B:

sinf A {    T foo() { /* ... */ };}sinf B uzaytiradi A {}

Ushbu Python misolida, sinf B oldinga foo usuli va x undagi ob'ektga mulk a maydon: ulardan foydalanish b (misol B) ularni ishlatish bilan bir xil b.a (misol A ularga yo'naltiriladi).

sinf A:    def sherzod(o'zini o'zi, x) -> Yo'q:        o'zini o'zi.x = x    def foo(o'zini o'zi):        chop etish(o'zini o'zi.x)sinf B:    def sherzod(o'zini o'zi, a) -> Yo'q:        o'zini o'zi.a = a    def foo(o'zini o'zi):        o'zini o'zi.a.foo()    @ mulk    def x(o'zini o'zi):        qaytish o'zini o'zi.a.x    @x.sozlovchi    def x(o'zini o'zi, x):        o'zini o'zi.a.x = x    @x.yo'q qilish    def x(o'zini o'zi):        del o'zini o'zi.a.xa = A(42)b = B(a)b.foo()  # "42" ni bosib chiqaradi.b.x  # "42" qiymati borb.x = 17   Endi # b.a.x qiymati 17 ga egadel b.x  # O'chiradi b.a.x.

Oddiy

Bunda Java misol Printer sinf bor chop etish usul. Ushbu bosib chiqarish usuli, bosib chiqarishni o'zi bajarishdan ko'ra, sinf ob'ektiga yo'naltiriladi RealPrinter. Tashqi dunyoga shunday ko'rinadi Printer ob'ekt bosib chiqarishni amalga oshirmoqda, lekin RealPrinter ob'ekt bu ishni bajaradigan narsa.

Ekspeditorlik shunchaki vazifani birovga / boshqa narsaga topshirishdir. Mana oddiy misol:

sinf RealPrinter { // "qabul qiluvchi"    bekor chop etish() {         Tizim.chiqib.println("Salom Dunyo!");     }}sinf Printer { // "jo'natuvchi"    RealPrinter p = yangi RealPrinter(); // qabul qiluvchini yaratish    bekor chop etish() {        p.chop etish(); // qabul qiluvchini chaqiradi    }} jamoat sinf Asosiy {    jamoat statik bekor asosiy(Ip[] dalillar) {        // tashqi dunyoga u Printer aslida bosib chiqaradiganga o'xshaydi.        Printer printer = yangi Printer();        printer.chop etish();    }}

Kompleks

Keyinchalik murakkab holat a Dekorativ naqsh yordamida interfeyslar, yo'naltirish yanada moslashuvchan bo'lishi mumkin va bosmaxona. "Moslashuvchanlik" bu degani C kerak emas A yoki B har qanday yo'l bilan, chunki ekspeditsiya kommutatsiyasi mavhum bo'lganidek C. Ushbu misolda sinf C interfeysni amalga oshiradigan har qanday sinfga yo'naltirishi mumkin Men. Sinf C boshqa ekspeditorga o'tish usuliga ega. Shu jumladan asboblar bandlar yaxshilanadi turdagi xavfsizlik, chunki har bir sinf interfeysdagi usullarni amalga oshirishi kerak. Asosiy savdo - bu ko'proq kod.

interfeys Men {	bekor f();	bekor g();} sinf A asboblar Men {	jamoat bekor f() { Tizim.chiqib.println("A: f () qilish"); }	jamoat bekor g() { Tizim.chiqib.println("A: g () qilish"); }} sinf B asboblar Men {	jamoat bekor f() { Tizim.chiqib.println("B: f () qilish"); }	jamoat bekor g() { Tizim.chiqib.println("B: g () qilish"); }} // amalga oshiriladigan ob'ektni ish vaqtida o'zgartirish (odatda kompilyatsiya vaqtida amalga oshiriladi)sinf C asboblar Men {	Men men = bekor;	// ekspeditorlik	jamoat C(Men men){ setI(men); }	jamoat bekor f() { men.f(); }	jamoat bekor g() { men.g(); } 	// normal atributlar	jamoat bekor setI(Men men) { bu.men = men; }} jamoat sinf Asosiy {	jamoat statik bekor asosiy(Ip[] dalillar) {		C v = yangi C(yangi A());		v.f();	// chiqish: A: f () qilish		v.g();	// chiqishi: A: doing g ()		v.setI(yangi B());		v.f();	// chiqish: B: f () qilish		v.g();	// chiqish: B: g () qilish	}}

Ilovalar

Ekspeditorlik ko'plab dizayn naqshlarida qo'llaniladi.[2] Ekspeditorlik to'g'ridan-to'g'ri bir nechta naqshlarda qo'llaniladi:

Ekspeditorlik boshqa naqshlarda ishlatilishi mumkin, lekin ko'pincha foydalanish o'zgartiriladi; Masalan, bitta ob'ektdagi usul chaqiruvi boshqasiga bir nechta turli xil usullarni chaqirishga olib keladi:

Adabiyotlar

  1. ^ a b v Büchi, Martin; Vek, Volfgang (2000). "Umumiy o'rashlar" (PDF). ECOOP 2000 - Ob'ektga yo'naltirilgan dasturlash. Kompyuter fanidan ma'ruza matnlari. 1850. pp.212–213. doi:10.1007/3-540-45102-1_10. ISBN  978-3-540-67660-7.
  2. ^ Gamma, Erix; Helm, Richard; Jonson, Ralf; Vlissidlar, Jon (1995). Dizayn naqshlari: Qayta foydalaniladigan ob'ektga yo'naltirilgan dasturiy ta'minot elementlari. Addison-Uesli. Bibcode:1995dper.book ..... G. ISBN  978-0-201-63361-0.