Adapter naqshlari - Adapter pattern

Yilda dasturiy ta'minot, adapter naqshlari a dasturiy ta'minot dizayni (shuningdek, o'ralgan deb nomlanadi, muqobil nomlash dekorativ naqsh ) imkon beradi interfeys mavjud bo'lgan sinf boshqa interfeys sifatida foydalanish uchun.[1] Bu ko'pincha mavjud sinflarni boshqalar bilan ishlashga majbur qilish uchun ishlatiladi manba kodi.

Masalan, a interfeysini o'zgartiradigan adapter Hujjat ob'ekti modeli ning XML ko'rsatilishi mumkin bo'lgan daraxt tuzilishiga hujjat.

Umumiy nuqtai

Adapter[2] dizayn naqshlari taniqli yigirma uchtadan biridir GoF dizayni naqshlari moslashuvchan va qayta ishlatilishi mumkin bo'lgan ob'ektga yo'naltirilgan dasturiy ta'minotni, ya'ni amalga oshirish, o'zgartirish, sinash va qayta ishlatishni osonlashtiradigan ob'ektlarni loyihalashtirish uchun takrorlanadigan dizayn muammolarini qanday hal qilishni tavsiflaydi.

Adapter dizayni naqshlari quyidagi muammolarni hal qiladi:[3]

  • Mijoz talab qiladigan interfeysga ega bo'lmagan sinfni qanday qilib qayta ishlatish mumkin?
  • Qanday qilib mos kelmaydigan interfeyslarga ega bo'lgan sinflar birgalikda ishlashi mumkin?
  • Qanday qilib sinf uchun muqobil interfeysni taqdim etish mumkin?

Ko'pincha (allaqachon mavjud bo'lgan) sinfni qayta ishlatish mumkin emas, chunki uning interfeysi mijozlar talab qiladigan interfeysga mos kelmaydi.

Adapter dizayni naqshida bunday muammolarni qanday hal qilish mumkinligi tasvirlangan:

  • Alohida belgilang adapter sinfning (mos kelmaydigan) interfeysini o'zgartiradigan sinf (moslashuvchan) boshqa interfeysga (nishon) mijozlar talab qiladi.
  • An orqali ishlash adapter kerakli interfeysga ega bo'lmagan sinflar bilan ishlash (qayta ishlatish).

Ushbu namunadagi asosiy g'oya - bu alohida-alohida ishlash adapter (allaqachon mavjud) sinf interfeysini o'zgartirmasdan moslashtiradigan.

Mijozlar a bilan ishlashlarini bilmaydilar nishon to'g'ridan-to'g'ri yoki an orqali sinf adapter ega bo'lmagan sinf bilan nishon interfeys.

Quyidagi UML sinf diagrammasiga ham qarang.

Ta'rif

Adapter ikkita mos kelmaydigan interfeyslarni birgalikda ishlashiga imkon beradi. Bu adapter uchun haqiqiy ta'rif. Interfeyslar mos kelmasligi mumkin, ammo ichki funktsionallik ehtiyojga mos kelishi kerak. Adapter dizayni naqshlari, aks holda mos kelmaydigan sinflarni bir sinf interfeysini mijozlar kutgan interfeysga aylantirish orqali birgalikda ishlashga imkon beradi.

Foydalanish

Qoplama ma'lum bir interfeysga hurmat ko'rsatishi va qo'llab-quvvatlashi kerak bo'lganda adapterdan foydalanish mumkin polimorfik xulq-atvor. Shu bilan bir qatorda, a dekorativ ish vaqtida interfeysning xatti-harakatlarini qo'shish yoki o'zgartirishga imkon beradi va a jabha asosiy ob'ektga osonroq yoki sodda interfeys kerak bo'lganda foydalaniladi.[4]

NaqshNiyat
Adapter yoki o'ramBir interfeysni boshqasiga o'zgartiradi, shunda u mijoz kutgan narsaga mos keladi
DekorativDastlabki kodni o'rash orqali interfeysga javobgarlik dinamik ravishda qo'shiladi
Delegatsiya"Meros bo'yicha kompozitsiyani" qo'llab-quvvatlash
FasadSoddalashtirilgan interfeysni taqdim etadi

Tuzilishi

UML sinf diagrammasi

Adapter dizayni namunasi uchun namunaviy UML sinf diagrammasi.[5]

Yuqorida UML sinf diagrammasi, mijoz talab qiladigan sinf nishon interfeysi qayta ishlatib bo'lmaydi moslashuvchan to'g'ridan-to'g'ri sinf, chunki uning interfeysi nishon interfeysi. Buning o'rniga mijoz orqali ishlaydi adapter amalga oshiradigan sinf nishon jihatidan interfeys moslashuvchan:

  • The ob'ekt adapteri usulini amalga oshiradi nishon ga tayinlash orqali interfeys moslashuvchan ish vaqtida ob'ekt (adaptee.specificOperation ()).
  • The sinf adapteri usulini amalga oshiradi nishon dan meros orqali interfeys moslashuvchan kompilyatsiya vaqtida sinf (specificOperation ()).

Ob'ekt adapteri namunasi

Ushbu adapter naqshida adapter o'zi o'ralgan sinf namunasini o'z ichiga oladi. Bunday holatda, adapter o'ralgan nusxaga qo'ng'iroqlarni amalga oshiradi ob'ekt.

Ob'ekt adapterining namunasi UML
Ob'ekt adapterining namunasi LePUS3

Sinf adapteri namunasi

Ushbu adapter naqshida bir nechta ishlatiladi polimorf interfeyslar kutilayotgan interfeysni ham, oldindan mavjud bo'lgan interfeysni ham amalga oshirish yoki meros qilib olish. Kutilayotgan interfeys sof sifatida yaratilishi uchun odatiy holdir interfeys sinf, ayniqsa tillar kabi Java qo'llab-quvvatlamaydigan (JDK 1.8 dan oldin) ko'p meros sinflar.[1]

Bilan ko'rsatilgan sinf adapteri namunasi UML.
Bilan ko'rsatilgan sinf adapteri namunasi LePUS3

Ish vaqti adapterining yana bir shakli

Kompilyatsiya vaqtining echimidan motivatsiya

Buning uchun kerakli sinf A etkazib berish sinf B ba'zi ma'lumotlar bilan, keling, ba'zilarini taxmin qilaylik Ip ma'lumotlar. Kompilyatsiya vaqtining echimi:

sinf B.setStringData(sinf A.getStringData());

Biroq, mag'lubiyat ma'lumotlarining formati har xil bo'lishi kerak deb taxmin qiling. Vaqtni kompilyatsiya qilish merosdan foydalanish:

jamoat sinf Format1ClassA uzaytiradi ClassA {    @Override    jamoat Ip getStringData() {        qaytish format(toString());    }}

va, ehtimol ish vaqti davomida to'g'ri "formatlash" ob'ektini zavod namunasi.

Ish vaqti adapterining echimi

"Adapterlar" yordamida echim quyidagicha amalga oshiriladi:

(i) vositachi "provayder" interfeysini aniqlang va ma'lumotlar manbasini o'rab turgan ushbu provayder interfeysini amalga oshiring, ClassA ushbu misolda va kerak bo'lganda formatlangan ma'lumotlarni chiqaradi:

jamoat interfeys StringProvider {    jamoat Ip getStringData();}jamoat sinf ClassAFormat1 asboblar StringProvider {    xususiy ClassA sinf A = bekor;    jamoat ClassAFormat1(final ClassA a) {        sinf A = a;    }    jamoat Ip getStringData() {        qaytish format(sinf A.getStringData());    }    xususiy Ip format(final Ip manba qiymati) {        // Manba qatorini kerakli formatga o'tkazing         // manba ob'ekti ma'lumotlariga muhtoj bo'lgan ob'ekt tomonidan        qaytish manba qiymati.qirqish();    }}

(ii) Provayderning aniq dasturini qaytaradigan adapter sinfini yozing:

jamoat sinf ClassAFormat1Adapter uzaytiradi Adapter {    jamoat Ob'ekt moslashmoq(final Ob'ekt anObject) {        qaytish yangi ClassAFormat1((ClassA) anObject);    }}

(iii) ro'yxatdan o'tkazing adapter global ro'yxatga olish kitobi bilan, shunday qilib adapter ish vaqtida qidirish mumkin:

AdapterFactory.getInstance().ro'yxatdan o'tgan Adapter(ClassA.sinf, ClassAFormat1Adapter.sinf, "format1");

(iv) Ma'lumotlarni uzatishni xohlaganingizda kodda ClassA ga Sinf B, yozing:

Adapter adapter =    AdapterFactory.getInstance()        .getAdapterFromTo(ClassA.sinf, StringProvider.sinf, "format1");StringProvider provayder = (StringProvider) adapter.moslashmoq(sinf A);Ip mag'lubiyat = provayder.getStringData();sinf B.setStringData(mag'lubiyat);

yoki aniqroq:

sinf B.setStringData(    ((StringProvider)            AdapterFactory.getInstance()                .getAdapterFromTo(ClassA.sinf, StringProvider.sinf, "format1")                .moslashmoq(sinf A))        .getStringData());

(v) Buning afzalligi shundaki, agar ma'lumotni ikkinchi formatda uzatish zarur bo'lsa, unda boshqa adapter / provayderni qidiring:

Adapter adapter =    AdapterFactory.getInstance()        .getAdapterFromTo(ClassA.sinf, StringProvider.sinf, "format2");

(vi) Va agar ma'lumotni chiqarish kerak bo'lsa ClassA kabi, masalan, rasm ma'lumotlari Sinf C:

Adapter adapter =    AdapterFactory.getInstance()        .getAdapterFromTo(ClassA.sinf, ImageProvider.sinf, "format2");ImageProvider provayder = (ImageProvider) adapter.moslashmoq(sinf A);sinf C.setImage(provayder.getImage());

(vii) Shu tarzda adapter va provayderlardan foydalanish bir nechta "ko'rish" ga imkon beradi Sinf B va ClassC ichiga ClassA sinf ierarxiyasini o'zgartirmasdan. Umuman olganda, u mavjud ob'ektlar ierarxiyasiga moslashtirilishi mumkin bo'lgan ob'ektlar o'rtasida o'zboshimchalik bilan ma'lumotlar oqimi mexanizmiga ruxsat beradi.

Adapter naqshini amalga oshirish

Adapter naqshini amalga oshirishda aniqlik uchun sinf nomini qo'llash mumkin [ClassName]Kimga[Interfeys]Adapter provayderni amalga oshirishga; masalan, DAOToProviderAdapter. Parametr sifatida adaptee sinf o'zgaruvchisiga ega bo'lgan konstruktor usuli bo'lishi kerak. Ushbu parametr, ning bir a'zosiga uzatiladi [ClassName]Kimga[Interfeys]Adapter. ClientMethod chaqirilganda, u moslashtirilgan shaxsning kerakli ma'lumotlariga kirish va kerakli natijani ishlab chiqaradigan ushbu operatsiyalarni bajarishga imkon beradigan moslashtirilgan modelga kirish huquqiga ega bo'ladi.

Java

interfeys Chaqmoq telefoni {    bekor zaryadlash();    bekor foydalanish Lightning();}interfeys MicroUsbPhone {    bekor zaryadlash();    bekor foydalanishMicroUsb();}sinf Iphone asboblar Chaqmoq telefoni {    xususiy mantiqiy ulagich;    @Override    jamoat bekor foydalanish Lightning() {        ulagich = to'g'ri;        Tizim.chiqib.println("Chaqmoq ulandi");    }    @Override    jamoat bekor zaryadlash() {        agar (ulagich) {            Tizim.chiqib.println("Zaryadlash boshlandi");            Tizim.chiqib.println("Zaryadlash tugadi");        } boshqa {            Tizim.chiqib.println("Avval chaqmoqni ulang");        }    }}sinf Android asboblar MicroUsbPhone {    xususiy mantiqiy ulagich;    @Override    jamoat bekor foydalanishMicroUsb() {        ulagich = to'g'ri;        Tizim.chiqib.println("MicroUsb ulangan");    }    @Override    jamoat bekor zaryadlash() {        agar (ulagich) {            Tizim.chiqib.println("Zaryadlash boshlandi");            Tizim.chiqib.println("Zaryadlash tugadi");        } boshqa {            Tizim.chiqib.println("Avval MicroUsb-ni ulang");        }    }}/ * manba ob'ektini o'rash paytida maqsad interfeysni ochish * /sinf LightningToMicroUsbAdapter asboblar MicroUsbPhone {    xususiy final Chaqmoq telefoni chaqmoq telefon;    jamoat LightningToMicroUsbAdapter(Chaqmoq telefoni chaqmoq telefon) {        bu.chaqmoq telefon = chaqmoq telefon;    }    @Override    jamoat bekor foydalanishMicroUsb() {        Tizim.chiqib.println("MicroUsb ulangan");        chaqmoq telefon.foydalanish Lightning();    }    @Override    jamoat bekor zaryadlash() {        chaqmoq telefon.zaryadlash();    }}jamoat sinf AdapterDemo {    statik bekor zaryadlash MicroUsbPhone(MicroUsbPhone telefon) {        telefon.foydalanishMicroUsb();        telefon.zaryadlash();    }    statik bekor zaryadlash LightningPhone(Chaqmoq telefoni telefon) {        telefon.foydalanish Lightning();        telefon.zaryadlash();    }    jamoat statik bekor asosiy(Ip[] kamon) {        Android android = yangi Android();        Iphone iPhone = yangi Iphone();        Tizim.chiqib.println("Androidni MicroUsb bilan zaryadlash");        zaryadlash MicroUsbPhone(android);        Tizim.chiqib.println("IPhone-ni chaqmoq bilan zaryadlash");        zaryadlash LightningPhone(iPhone);        Tizim.chiqib.println("IPhone-ni MicroUsb bilan zaryadlash");        zaryadlash MicroUsbPhone(yangi LightningToMicroUsbAdapter (iPhone));    }}

Chiqish

MicroUsbMicroUsb ulangan holda androidni zaryadlash Zaryadlash boshlandi Zaryadlash tugallandiPhone-ni chaqmoq bilan ulash Zaryadlash boshlandi Zaryadlash tugallandi IPhone-ni MicroUsbMicroUsb ulangan holda zaryadlashBoldirish boshlandi Zaryadlash tugallandi

Python

"""Adapter naqsh namunasi."""dan abc Import ABCMeta, mavhum usulYO'Q_O'QING = "Siz buni amalga oshirishingiz kerak."ZARJ = ["Zaryadlash boshlandi.", "Zaryadlash tugadi."]POWER_ADAPTERS = {"Android": "MicroUSB", "iPhone": "Chaqmoq"}ULANILGAN = "{} ulangan. "CONNECT_FIRST = "Ulanmoq {} birinchi. "sinf RechargeTemplate:    nilufar__ = ABCMeta    @abstractmethod    def zaryadlash(o'zini o'zi):        oshirish NotImplementedError(YO'Q_O'QING)sinf FormatIphone(RechargeTemplate):    @abstractmethod    def use_lightning(o'zini o'zi):        oshirish NotImplementedError(YO'Q_O'QING)sinf FormatAndroid(RechargeTemplate):    @abstractmethod    def use_micro_usb(o'zini o'zi):        oshirish NotImplementedError(YO'Q_O'QING)sinf IPhone(FormatIphone):    __name__ = "iPhone"    def sherzod(o'zini o'zi):        o'zini o'zi.ulagich = Yolg'on    def use_lightning(o'zini o'zi):        o'zini o'zi.ulagich = To'g'ri        chop etish(ULANILGAN.format(POWER_ADAPTERS[o'zini o'zi.__name__]))    def zaryadlash(o'zini o'zi):        agar o'zini o'zi.ulagich:            uchun davlat yilda QAYTIRISH:                chop etish(davlat)        boshqa:            chop etish(CONNECT_FIRST.format(POWER_ADAPTERS[o'zini o'zi.__name__]))sinf Android(FormatAndroid):    __name__ = "Android"    def sherzod(o'zini o'zi):        o'zini o'zi.ulagich = Yolg'on    def use_micro_usb(o'zini o'zi):        o'zini o'zi.ulagich = To'g'ri        chop etish(ULANILGAN.format(POWER_ADAPTERS[o'zini o'zi.__name__]))    def zaryadlash(o'zini o'zi):        agar o'zini o'zi.ulagich:            uchun davlat yilda ZARJ:                chop etish(davlat)        boshqa:            chop etish(CONNECT_FIRST.format(POWER_ADAPTERS[o'zini o'zi.__name__]))sinf IPhoneAdapter(FormatAndroid):    def sherzod(o'zini o'zi, mobil):        o'zini o'zi.mobil = mobil    def zaryadlash(o'zini o'zi):        o'zini o'zi.mobil.zaryadlash()    def use_micro_usb(o'zini o'zi):        chop etish(ULANILGAN.format(POWER_ADAPTERS["Android"]))        o'zini o'zi.mobil.use_lightning()sinf AndroidRecharger:    def sherzod(o'zini o'zi):        o'zini o'zi.telefon = Android()        o'zini o'zi.telefon.use_micro_usb()        o'zini o'zi.telefon.zaryadlash()sinf IPhoneMicroUSBR zaryadlovchi:    def sherzod(o'zini o'zi):        o'zini o'zi.telefon = IPhone()        o'zini o'zi.telefon_adapteri = IPhoneAdapter(o'zini o'zi.telefon)        o'zini o'zi.telefon_adapteri.use_micro_usb()        o'zini o'zi.telefon_adapteri.zaryadlash()sinf IPhoneRecharger:    def sherzod(o'zini o'zi):        o'zini o'zi.telefon = IPhone()        o'zini o'zi.telefon.use_lightning()        o'zini o'zi.telefon.zaryadlash()chop etish("Android-ni MicroUSB zaryadlovchi bilan zaryadlash.")AndroidRecharger()chop etish()chop etish("IPhone-ni adapter naqshidan foydalanib MicroUSB bilan zaryadlash.")IPhoneMicroUSBR zaryadlovchi()chop etish()chop etish("IPhone-ni zaryadlovchi bilan zaryadlash.")IPhoneRecharger()

Shuningdek qarang

Adabiyotlar

  1. ^ a b Freeman, Erik; Friman, Elisabet; Serra, Keti; Bates, Bert (2004). Birinchi dizayn naqshlarini boshlang. O'Reilly Media. p. 244. ISBN  978-0-596-00712-6. OCLC  809772256. Arxivlandi asl nusxasi (qog'ozli) 2013-05-04 da. Olingan 2013-04-30.
  2. ^ Gamma, Erix; Helm, Richard; Jonson, Ralf; Vlissidlar, Jon (1994). Dizayn naqshlari: Qayta foydalaniladigan ob'ektga yo'naltirilgan dasturiy ta'minot elementlari. Addison Uesli. pp.139ff. ISBN  0-201-63361-2.
  3. ^ "Adapter dizayni namunasi - muammo, echim va qo'llanilishi". w3sDesign.com. Olingan 2017-08-12.
  4. ^ Freeman, Erik; Friman, Elisabet; Serra, Keti; Bates, Bert (2004). Xendrikson, Mayk; Loukides, Mayk (tahrir). Birinchi dizayn naqshlarini boshlang (qog'ozli). 1. O'Reilly Media. 243, 252, 258, 260-betlar. ISBN  978-0-596-00712-6. Olingan 2012-07-02.
  5. ^ "Adapter dizayni namunasi - Tuzilishi va hamkorlik". w3sDesign.com. Olingan 2017-08-12.