Ob'ektni nusxalash - Object copying

Yilda ob'ektga yo'naltirilgan dasturlash, ob'ektni nusxalash bu yaratish mavjud bo'lgan nusxasi ob'ekt, ob'ektga yo'naltirilgan dasturlashdagi ma'lumotlar birligi. Olingan ob'ekt an deb nomlanadi ob'ekt nusxasi yoki oddiygina nusxa ko'chirish asl ob'ektning. Nusxalash asosiy, ammo nozik xususiyatlarga ega va qo'shimcha xarajatlarga ega bo'lishi mumkin. Ob'ektni nusxalashning bir necha usullari mavjud, ko'pincha a nusxa ko'chirish konstruktori yoki klonlash. Nusxalash asosan nusxani o'zgartirish yoki ko'chirish yoki joriy qiymatni saqlab qolish uchun amalga oshiriladi. Agar ulardan birortasi kerak bo'lmasa, asl ma'lumotlarga murojaat qilish etarli va samaraliroq bo'ladi, chunki nusxa ko'chirish sodir bo'lmaydi.

Umumiy do'kondagi ob'ektlar kompozit ma'lumotlar. Oddiy hollarda nusxa ko'chirish yangi, boshlanmagan ob'ektni ajratish va barcha maydonlarni nusxalash orqali amalga oshirilishi mumkin (atributlar ) asl ob'ektdan, yanada murakkab holatlarda bu istalgan xatti-harakatga olib kelmaydi.

Nusxalash usullari

Ko'pgina ob'ektlarni loyihalashtirish maqsadi bitta monolitik blokdan yasalganga o'xshashlikni berishdir, garchi aksariyati yo'q. Ob'ektlar bir nechta turli qismlardan tashkil topganligi sababli nusxa ko'chirish ahamiyatsiz bo'ladi. Ushbu muammoni hal qilish uchun bir nechta strategiyalar mavjud.

X maydonlarini o'z ichiga olgan A ob'ektini ko'rib chiqingmen (aniqrog'i, A mag'lubiyatga va x ga e'tibor beringmen uning belgilaridan iborat qator). Deb nomlangan A nusxasini olish uchun turli xil strategiyalar mavjud sayoz nusxa va chuqur nusxa. Ko'pgina tillar ikkitasini yoki birini belgilaydigan strategiya bo'yicha umumiy nusxalashga imkon beradi nusxa ko'chirish operatsiya yoki alohida sayoz nusxa va chuqur nusxa operatsiyalar.[1] E'tibor bering, undan ham sayozroq ma'lumotnoma mavjud bo'lgan A ob'ektiga, bu holda yangi ob'ekt yo'q, faqat yangi ma'lumotnoma.

Ning terminologiyasi sayoz nusxa va chuqur nusxa sanalari Kichik munozarasi -80.[2] Ob'ektlarni tenglik uchun taqqoslashda bir xil farq mavjud: asosan, tenglik (bir xil ob'ekt) va tenglik (bir xil qiymat) o'rtasida farq mavjud bo'lib, ular sayoz tenglikka va (1 darajali) ikkita tenglamaga mos keladigan tenglikka mos keladi, ammo keyinchalik tenglik bo'ladimi? faqat ko'rib chiqilayotgan ob'ekt maydonlarini taqqoslashni yoki ba'zi bir maydonlarni ajratib ko'rsatishni va ularning qiymatlarini o'z navbatida taqqoslashni anglatadi (masalan, ikkita bog'langan ro'yxat, agar ular bir xil tugunlarga ega bo'lsa yoki ular bir xil qiymatga ega bo'lsa?).[tushuntirish kerak ]

Sayoz nusxa

Ob'ektni nusxalash usullaridan biri bu sayoz nusxa. U holda yangi B ob'ekt yaratilgan va A maydonlarining qiymatlari B ga ko'chiriladi.[3][4][5][6] Bu shuningdek a nusxa ko'chirish,[7][8][9] daladan maydonga nusxa ko'chirish, yoki maydon nusxasi.[10] Agar maydon qiymati ob'ektga havola bo'lsa (masalan, xotira manzili) u ma'lumotnomani nusxa ko'chiradi, shuning uchun A bilan bir xil ob'ektga ishora qiladi va agar maydon qiymati ibtidoiy tur bo'lsa, u ibtidoiy turning qiymatini ko'chiradi. Ibtidoiy turlarga ega bo'lmagan tillarda (hamma narsa ob'ekt bo'lgan joyda), B nusxasining barcha maydonlari asl A maydonlari bilan bir xil narsalarga havolalardir. birgalikda, shuning uchun agar ushbu ob'ektlardan biri o'zgartirilgan bo'lsa (A yoki B dan), o'zgarish boshqasida ko'rinadi. Sayoz nusxalar oddiy va odatda arzon, chunki ular odatda bitlarni to'liq nusxalash orqali amalga oshirilishi mumkin.

Chuqur nusxa

Amaldagi chuqur nusxa.
Amaldagi chuqur nusxa.
Chuqur nusxa to'ldirildi.
Chuqur nusxa to'ldirildi.

Shu bilan bir qatorda chuqur nusxa, ya'ni maydonlar ajratilganligini anglatadi: nusxa ko'chiriladigan ob'ektlarga havolalar o'rniga, har qanday havola qilingan ob'ektlar uchun yangi nusxa ko'chirish moslamalari yaratiladi va ularga havolalar B ga joylashtiriladi. Natija sayoz nusxasi natijadan farq qiladi B nusxasi havola qilingan ob'ektlar A havolasi bilan ajralib turadigan va mustaqil bo'lganligi bilan. Chuqur nusxalar qo'shimcha moslamalarni yaratish zarurati tufayli ancha qimmatga tushadi va murakkab grafikni shakllantirgan ma'lumotlarga ko'ra ancha murakkab bo'lishi mumkin.

Chuqur nusxalash - bu nusxalash jarayoni rekursiv tarzda sodir bo'ladigan jarayon. Bu avval yangi kollektsiya ob'ekti qurishni, so'ngra uni asl nusxada topilgan ob'ektlar nusxalari bilan rekursiv ravishda to'ldirishni anglatadi. Chuqur nusxa ko'chirilgan bo'lsa, ob'ekt nusxasi boshqa ob'ektga ko'chiriladi. Bu shuni anglatadiki, ob'ekt nusxasiga kiritilgan har qanday o'zgarishlar asl ob'ektda aks etmaydi. Pythonda bu "deepcopy ()" funktsiyasi yordamida amalga oshiriladi.

Kombinatsiya

Keyinchalik murakkab holatlarda, nusxadagi ba'zi maydonlarda "assotsiatsiya" munosabatlariga mos keladigan asl ob'ekt bilan (sayoz nusxadagi kabi) umumiy qiymatlar bo'lishi kerak; va ba'zi maydonlarda "to'plash" munosabatlariga mos keladigan nusxalar bo'lishi kerak (chuqur nusxadagi kabi). Bunday hollarda, odatda nusxalashni odatiy ravishda amalga oshirish talab qilinadi; bu masala va echimi Smalltalk-80ga tegishli.[11] Shu bilan bir qatorda, maydonlarni sayoz nusxa ko'chirish yoki chuqur nusxa ko'chirishni talab qilish va avtomatik ravishda hosil qilingan nusxa ko'chirish operatsiyalari talab qilinadi (xuddi shunday taqqoslash operatsiyalari uchun).[1] Bu aksariyat ob'ektga yo'naltirilgan tillarda amalga oshirilmaydi, ammo Eyfelda qisman qo'llab-quvvatlash mavjud.[1]

Amalga oshirish

Hammasi deyarli ob'ektga yo'naltirilgan dasturlash tillari ob'ektlarni nusxalashning biron bir usulini taqdim eting. Ko'pgina tillar dasturlar uchun ko'pgina ob'ektlarni ta'minlamaganligi sababli, dasturchi ob'ektni qanday nusxalash kerakligini belgilashi kerak, xuddi ular avval ikkita ob'ekt bir xil yoki hatto taqqoslanadigan bo'ladimi-yo'qligini aniqlashi kerak. Ko'pgina tillar ba'zi odatiy xatti-harakatlarni ta'minlaydi.

Nusxalashning echimi har bir tilda va u qanday ob'ekt tushunchasiga ega ekanligi bilan farq qiladi.

Dangasa nusxa

Dangasa nusxa bu chuqur nusxani amalga oshirishdir. Dastlab ob'ektni nusxalashda (tez) sayoz nusxa ishlatiladi. Hisoblagich ma'lumotlarning qancha ob'ektlar bilan bo'lishishini kuzatish uchun ham ishlatiladi. Dastur ob'ektni o'zgartirmoqchi bo'lganda, ma'lumotlar almashinishini (hisoblagichni o'rganish orqali) aniqlay oladi va agar kerak bo'lsa, chuqur nusxa ko'chirishi mumkin.

Dangasa nusxa tashqi tomonga xuddi chuqur nusxa kabi ko'rinadi, ammo imkoni boricha sayoz nusxaning tezligidan foydalanadi. Kamchiliklari hisoblagich tufayli juda yuqori, ammo doimiy asosiy xarajatlar. Shuningdek, ba'zi holatlarda, dumaloq ma'lumotnomalar muammolarni keltirib chiqarishi mumkin.

Dangasa nusxa bilan bog'liq nusxa ko'chirish.

Java-da

Quyida eng ko'p ishlatiladigan ob'ektga yo'naltirilgan tillardan biriga misollar keltirilgan, Java, ob'ektga yo'naltirilgan til ushbu muammoni hal qilishning deyarli barcha usullarini qamrab olishi kerak.

C ++ dan farqli o'laroq, Java-dagi ob'ektlarga doimo bilvosita kirish orqali kirish mumkin ma'lumotnomalar. Ob'ektlar hech qachon bevosita yaratilmaydi, aksincha har doim mos yozuvlar o'zgaruvchisi tomonidan uzatiladi yoki tayinlanadi. (Java-dagi usullar doimo qiymatdan o'tishammo, bu mos yozuvlar o'zgaruvchisining qiymati uzatilmoqda.)[12] The Java virtual mashinasi boshqaradi axlat yig'ish shunday qilib ob'ektlar ularga etib bo'lmaydigan bo'lganidan keyin tozalanadi. Java-da biron bir ob'ektni nusxalashning avtomatik usuli yo'q.

Nusxalash odatda a tomonidan amalga oshiriladi clone () usuli sinf. Ushbu usul, odatda, o'z navbatida, nusxasini olish uchun o'zining ota-sinfidagi clone () usulini chaqiradi va keyinchalik nusxalashning istalgan tartib-qoidalarini bajaradi. Oxir oqibat bu klon () uslubiga o'tadi Ob'ekt (eng yuqori sinf), bu ob'ekt bilan bir xil sinfning yangi nusxasini yaratadi va barcha maydonlarni yangi nusxaga ko'chiradi ("sayoz nusxa"). Agar ushbu usul ishlatilsa, sinf Klonlash mumkin marker interfeysi, aks holda shunday bo'ladi otish CloneNotSupportedException. Ota-onadan nusxasini olgandan so'ng, sinfning o'ziga xos klon () usuli, keyinchalik chuqur nusxalash (masalan, ob'ekt tomonidan ko'rsatilgan ba'zi tuzilmalarning nusxalarini ko'paytirish) yoki yangi nusxaga yangi noyob identifikatorni berish kabi maxsus klonlash imkoniyatini berishi mumkin.

Klonning qaytish turi () Ob'ekt, lekin klon usulini amalga oshiruvchilar Java-ning qo'llab-quvvatlashi tufayli uning o'rniga klonlanadigan ob'ekt turini yozishlari mumkin edi kovariant qaytish turlari. Klon () dan foydalanishning bir afzalligi shundaki, u an bekor qilinadigan usul, biz har qanday ob'ektda clone () ni chaqira olamiz va u o'z sinfining clone () usulidan foydalanadi, chaqiruv kodi bu sinf nima ekanligini bilishni talab qilmaydi (bu nusxa konstruktori bilan kerak bo'ladi).

Kamchilik shundaki, tez-tez mavhum turdagi clone () uslubiga kirish mumkin emas. Ko'pchilik interfeyslar va mavhum darslar Java-da umumiy klon () usulini ko'rsatmang. Shunday qilib, ko'pincha klon () usulidan foydalanishning yagona usuli bu ob'ektning klassi ma'lum bo'lsa, bu mumkin bo'lgan eng umumiy turdan foydalanishning mavhumlik printsipiga ziddir. Masalan, Java-da List ma'lumotlariga ega bo'lsa, ushbu havolada clone () ni chaqira olmaydi, chunki List hech qanday ommaviy clone () usulini ko'rsatmaydi. ArrayList va LinkedList kabi List dasturlarining bajarilishlari umuman clone () usullariga ega, ammo ob'ektning sinf turini o'tkazish noqulay va yomon mavhumlikdir.

Ob'ektlarni Java-da nusxalashning yana bir usuli bu seriyalash ularni orqali Serializable interfeys. Bu odatda uchun ishlatiladi qat'iyat va simli protokol maqsadlar, lekin u ob'ektlarning nusxalarini yaratadi va klondan farqli o'laroq, ob'ektlarning tsiklli grafikalarini oqilona ishlov beradigan chuqur nusxasi dasturchining minimal kuchi bilan osonlikcha mavjud.

Ushbu ikkala usul ham e'tiborga loyiq muammolardan aziyat chekmoqda: konstruktor klon yoki seriyalash bilan nusxalangan ob'ektlar uchun ishlatilmaydi. Bu noto'g'ri boshlangan ma'lumotlar bilan xatolarga olib kelishi mumkin, ulardan foydalanishni oldini oladi final a'zo maydonlari va parvarishlashni qiyinlashtiradi. Ba'zi kommunal xizmatlar ushbu muammolarni chuqur klonlash kutubxonasi kabi ob'ektlarni chuqur nusxalash uchun aks ettirish yordamida bartaraf etishga harakat qilmoqdalar.[13]

Eyfelda

Ish vaqti moslamalari Eyfel orqali bilvosita mavjud ma'lumotnomalar yoki kabi kengaytirilgan maydonlari ularni ishlatadigan ob'ektlar ichiga o'rnatilgan ob'ektlar. Ya'ni, ob'ektning maydonlari ham saqlanadi tashqi yoki ichki.

Eyfel sinfi HAMMA ob'ektlarni sayoz va chuqur nusxalash va klonlash xususiyatlarini o'z ichiga oladi. Eyfelning barcha sinflari meros qilib olinadi HAMMA, shuning uchun bu funktsiyalar barcha sinflarda mavjud bo'lib, mos yozuvlar va kengaytirilgan ob'ektlar uchun ham qo'llaniladi.

The nusxa ko'chirish xususiyati bir ob'ektdan ikkinchisiga sayoz, maydonma-nusxa ko'chirishni ta'sir qiladi. Bunday holda yangi ob'ekt yaratilmaydi. Agar y nusxa ko'chirildi x, keyin havola qilingan bir xil ob'ektlar y dasturidan oldin nusxa ko'chirish, shuningdek, havola qilinadi x keyin nusxa ko'chirish xususiyati tugaydi.

Sayoz nusxasi bo'lgan yangi ob'ektni yaratishga ta'sir qilish y, xususiyati egizak ishlatilgan. Bunday holda, maydonlari manba maydonlari bilan bir xil bo'lgan bitta yangi ob'ekt yaratiladi.

Xususiyat egizak xususiyatga tayanadi nusxa ko'chirish, bu avlodlarda qayta belgilanishi mumkin HAMMA, agar kerak bo'lsa. Natijasi egizak langar turiga kiradi hozirgi kabi.

Chuqur nusxalash va chuqur egizaklarni yaratish funktsiyalar yordamida amalga oshirilishi mumkin chuqur_ nusxa ko'chirish va chuqur_twin, yana sinfdan meros bo'lib o'tgan HAMMA. Ushbu xususiyatlar ko'plab yangi ob'ektlarni yaratish imkoniyatiga ega, chunki ular butun ob'ekt tarkibidagi barcha moslamalarni takrorlaydi. Mavjud ob'ektlarga havolalarni oddiygina nusxalash o'rniga yangi takrorlanadigan ob'ektlar yaratilganligi sababli, chuqur operatsiyalar sayoz operatsiyalarga qaraganda tezroq ishlash muammolari manbaiga aylanadi.

Boshqa tillarda

Yilda C # interfeysdan foydalanish o'rniga Faqatgina, aks ettirish yordamida chuqur nusxa yaratish uchun umumiy kengaytma usuli ishlatilishi mumkin. Buning ikkita afzalligi bor: Birinchidan, qo'lda nusxa olinadigan har bir xususiyat va o'zgaruvchini ko'rsatmasdan har qanday ob'ektni nusxalashning moslashuvchanligini ta'minlaydi. Ikkinchidan, turi umumiy bo'lganligi sababli, kompilyator maqsad ob'ekti va manba ob'ekti bir xil turga ega bo'lishini ta'minlaydi.

Yilda Maqsad-C, usullari nusxa ko'chirish va mutableCopy barcha ob'ektlar tomonidan meros bo'lib olingan va nusxalarini bajarish uchun mo'ljallangan; ikkinchisi asl ob'ektning o'zgaruvchan turini yaratish uchun. Ushbu usullar o'z navbatida copyWithZone va mutableCopyWithZone nusxalashni amalga oshirish uchun navbati bilan usullar. Ob'ekt mos keladigan narsani amalga oshirishi kerak copyWithZone nusxa ko'chirish usuli.

Yilda OCaml, kutubxona funktsiya Nusxa ko'chirish ob'ektni sayoz nusxalashni amalga oshiradi.

Yilda Python, kutubxonaning nusxa ko'chirish moduli sayoz nusxalarni va ob'ektlarning chuqur nusxalarini beradi nusxa ko'chirish () va chuqur nusxa ko'chirish () navbati bilan funktsiyalar.[14] Dasturchilar maxsus usullarni belgilashlari mumkin __ nusxasi __ () va __ nusxa ko'chirish __ () maxsus nusxalashni amalga oshirishni ta'minlash uchun ob'ektda.

Yilda Yoqut, barcha ob'ektlar sayoz nusxalarni bajarish uchun ikkita usulni egallaydi, klonlash va dup. Ikki usul shu bilan farq qiladi klonlash ob'ektning buzilgan holatini, muzlatilgan holatini va boshqa har qanday narsani nusxa ko'chiradi singleton usullari bo'lishi mumkin, aksincha dup faqat uning iflos holatini nusxa ko'chiradi. Chuqur nusxalarga ob'ektning bayt oqimini tashlab yuborish yoki yuklash yoki YAML seriyalash orqali erishish mumkin.[1] Shu bilan bir qatorda, siz o'zingizning grafikalaringizning chuqur nusxasini olish uchun deep_dive gemidan foydalanishingiz mumkin. [2]

Yilda Perl, ichki tuzilmalar havolalar yordamida saqlanadi, shuning uchun ishlab chiquvchi butun tuzilishni aylanib chiqishi va ma'lumotlarga qayta murojaat qilishi yoki dclone () moduldan funktsiya Saqlanadigan.

Yilda VBA, turdagi o'zgaruvchilarning tayinlanishi Ob'ekt sayoz nusxa bo'lib, boshqa barcha turlari uchun topshiriq (raqamli turlar, String, foydalanuvchi tomonidan belgilangan turlar, massivlar) chuqur nusxadir. Shunday qilib kalit so'z O'rnatish topshiriq uchun sayoz nusxa va (ixtiyoriy) kalit so'z signal beradi Ruxsat bering chuqur nusxaga ishora qiladi. VBA-da Ob'ektlarning chuqur nusxalari uchun o'rnatilgan usul mavjud emas.

Shuningdek qarang

Izohlar

  1. ^ a b v Grogono va Sakkinen 2000 yil.
  2. ^ Goldberg va Robson 1983 yil, 97-99 betlar. "Ob'ekt nusxalarini olishning ikki yo'li mavjud. Farq shundaki, ob'ekt o'zgaruvchilarining qiymatlari ko'chirilishi yoki ko'chirilmasligi. Agar qiymatlar ko'chirilmasa, ular birgalikda bo'lishadi (sayoz nusxa ko'chirish); agar qiymatlar ko'chirilgan bo'lsa, ular taqsimlanmaydi (chuqur nusxa ko'chirish)."
  3. ^ "C ++ Shallow va chuqur nusxasini tushuntirish".
  4. ^ ".NET Shallow va boshqalar chuqur nusxasini tushuntirish".
  5. ^ "Java Shallow va chuqur nusxa ko'chirishni tushuntirish".
  6. ^ "Umumiy sayoz va chuqur nusxa ko'chirishni tushuntirish". Arxivlandi asl nusxasi 2016-03-04 da. Olingan 2013-04-10.
  7. ^ Asosiy Java: asoslar, 1-jild, p. 295
  8. ^ Samarali Java, Ikkinchi nashr, p. 54
  9. ^ "Ob'ekt.clone () tomonidan bajarilgan ushbu nusxa ko'chirish nima? ", Stack overflow
  10. ^ "Josh Bloch dizayn bo'yicha: samarali Java muallifi bilan suhbat, Josh Bloch", Bill Venners, JavaWorld, 2002 yil 4-yanvar, p. 13
  11. ^ Goldberg va Robson 1983 yil, p. 97. "ning standart bajarilishi nusxa ko'chirish bu sayoz nusxa ko'chirish. Nusxalash umumiy va almashilmagan o'zgaruvchilarning maxsus birikmasiga olib kelishi kerak bo'lgan subklasslarda odatda nusxa olish bilan bog'liq bo'lgan usul emas, aksincha nusxa bilan bog'langan usul amalga oshiriladi. sayoz nusxa ko'chirish yoki chuqur nusxa ko'chirish."
  12. ^ "Axborotni uslub yoki konstruktorga etkazish". Olingan 8 oktyabr 2013.
  13. ^ Java chuqur klonlash kutubxonasi
  14. ^ Python nusxa ko'chirish moduli

Adabiyotlar