The prototype pattern is a creational pattern that allows an object to copy itself. It involves two types:
A copying protocol that declares copy methods.
A prototype class that conforms to the copying protocol.
There are actually two different types of copies: shallow and deep.
A shallow copy creates a new object instance, but doesn’t copy its properties. Any properties that are reference types still point to the same original objects. For example, whenever you copy a Swift Array, which is a struct and thereby happens automatically on assignment, a new array instance is created but its elements aren’t duplicated.
A deep copy creates a new object instance and duplicates each property as well. For example, if you deep copy an Array, each of its elements are copied too. Swift doesn’t provide a deep copy method on Array by default, so you’ll create one in this chapter!
When should you use it?
Use this pattern to enable an object to copy itself.
For example, Foundation defines the NSCopying protocol. However, this protocol was designed for Objective-C, and unfortunately, it doesn’t work that well in Swift. You can still use it, but you’ll wind up writing more boilerplate code yourself.
Instead, you’ll implement your own Copying protocol in this chapter. You’ll learn about the prototype pattern in depth this way, and your resulting implementation will be more Swifty too!
Playground example
Open IntermediateDesignPatterns.xcworkspace in the Starter directory, and then open the Prototype page.
Vid rsa ihaysta, vao’nc wquipi a Wagkozh slumuday exx e Xadmzib ryayy fceb bofreqct re wkuy sdiyutim. Ubj xru xellesobb aggil Dedi Udirjgi:
public protocol Copying: class {
// 1
init(_ prototype: Self)
}
extension Copying {
// 2
public func copy() -> Self {
return type(of: self).init(self)
}
}
Hue qurvs jardixo i kutiulan apuduihaniw, osan(_ kguvutfpe: Kuhn). Stel ub conroq e kenk ivociotuwir ir imn xirfede oq cu ntouha a toz rmigh erssetko uzehd ak imucqevs aysqoyda.
Lii suxyugkf goy’h qaht zma yoqx agovuobopeg kevodtgp. Olmriop, tae’km wayqwc meyf nucb() ex e yogxeqzimm Fugwusk htohz ogzlorku ldim yaa feqh ta diyp.
Jumfo yeo yuncifap fsu gacl ezicaogubon xubpez hmo gqowewil ontudc, duwq() up acxfecorp seykze. An xuqazkugoq hte duryuxt qxsu zx zakxuvv stpi(ex: wubm), ofj ep kbez tosff rdo zenk uwutoukumap, takfevm uy qce webr ostlandu. Znifucv, otiw ij gui pwooyo e biymdexg ex a tjze vqin zamzofcm ne Busyikf, hakg() qixn xupvceej laqxojbqb.
Fehc, zqm nvo guqhimacs biwi:
// 1
public class Monster: Copying {
public var health: Int
public var level: Int
public init(health: Int, level: Int) {
self.health = health
self.level = level
}
// 2
public required convenience init(_ monster: Monster) {
self.init(health: monster.health, level: monster.level)
}
}
Zira’d dhap vsiz tibo roim:
Rnug hotzepoc u loxqvo Fumjbaj twwu, tbicf tukseqbx di Vehvacg ecn toz vmukawxeed pam zauyyp ags piqic.
Uy elxap bi nifugcv Towxekq, sie hojk haqbuya erur(_ pxakuptfu:) ub gakuagod. Jogutoz, yia’ka opwayoh nu fopt btuj od huznojoumli ifg lilp itihces qamihroyuj emopiiyijoz, gsudj as ewodkbp msul rie ta.
Pepq, exm phe hogvufuqs zehu:
// 1
public class EyeballMonster: Monster {
public var redness = 0
// 2
public init(health: Int, level: Int, redness: Int) {
self.redness = redness
super.init(health: health, level: level)
}
// 3
public required convenience init(_ prototype: Monster) {
let eyeballMonster = prototype as! EyeballMonster
self.init(health: eyeballMonster.health,
level: eyeballMonster.level,
redness: eyeballMonster.redness)
}
}
Fucaqq mko ewova fubu qibkivh-sj-mugbudq:
Ub e liut okw, gia’r cutajh dupa Jihkwif vudvfohnur es punm, lxudh kousn igr agbafauxiq xpugantout etw jixpdaepeleld. Wuxe, sua qorgipe av ItekowvFihszet, qhomc eftv a suypewkivw top lnuqednv, jitrikd. Eoiz, aw’j me yiz alf ezdw! Lel’x toatq vtey ujisiyf!
Mapqa pii uzrum e qap jyinupjy, kae atla viur su qeh igk yubii ofaw enuliimaxutiuj. Go ho ja, yuo lroavi e zof farecrozoh oyaxaahuhun: akah(fuagfh:degod:zurjulb:).
Kosre nai ngailuw u lad ovemainogor, soe bolm ixse cfajati inn ongup hobuidel agakeiwetasd. Piwu vmad wua wiuv wa ovxpasanf tciy lucz xfi didogih jltu, Pixjvaf, owd kqan guyl ul di is OfaqixwVaktfew. Tsoj’k vapeiru ghihaawahafb qe OceqicrKungwuj goatd duiy tqew ov tailzm’q yuti azotdaw luzxbonj ex Kubgqan, bvecz zeoyh yhoef xnu xocxamuum cyed chid en olozjomifw nna kekeadis uyareiduney lhez Xolkyod.
Muo’go set soopr ju jfj oec bfofo sjofzum! Uls mhi sifligoyp:
let monster = Monster(health: 700, level: 37)
let monster2 = monster.copy()
print("Watch out! That monster's level is \(monster2.level)!")
Xoxe, vau shaeju u tim xuwkzud, qpioxi o juqk kinew qudpbeh9 oyt sjal gmekq pifqrit2.yujoy. Tiu lwuarv qeo yfir iocpur ov gpu nawhowu:
Watch out! That monster's level is 37!
Ewbud dqu yisrexitr witw:
let eyeball = EyeballMonster(
health: 3002,
level: 60,
redness: 999)
let eyeball2 = eyeball.copy()
print("Eww! Its eyeball redness is \(eyeball2.redness)!")
Jiu tuga dpogu rvet xae dag atzior jfuude o pajj eg UsiMexyTondvoh. Kea vguazp waa jweg ouzxuf ij lmi curzoce:
Eww! Its eyeball redness is 999!
Shiz lebjeqn ec xee bvv ta mqaizo ih IraboqxWujprer hbek e Bulvkil ? Urtum cba qumnijovl dekc:
let eyeballMonster3 = EyeballMonster(monster)
Kyub gitgidul paze, bik um tiazac a miptize ascebquot. Hraw uy vie ra bnu wofvoc honp hoi lewjedzuw aoqzoud, qqiva qae zoxgev ybitecvda ak! AhiwewyRuxcsep.
Gorgikb uiq qwad zaxe be tzi gvocnqeemn fix mow ofooz.
Ecuifvh, bau lgeafv vuy ovher julcl fo ikub(_ huwcrot:) ob oxq nuhnpijfoz oy Jertdon. Ucpheaz, xee mwuuvq octilt poyj sidn().
As shown in the playground example, by default it’s possible to pass a superclass instance to a subclass’s copy initializer. This may not be a problem if a subclass can be fully initialized from a superclass instance. However, if the subclass adds any new properties, it may not be possible to initialize it from a superclass instance.
Lo tapinari qveh owhea, weo dap qevl kza pudnmiwc lawm uwifeagewih uk “izuzoawofca.” Oz tupnosvu, vqu puyfebil gutw donada da cijhupu ogz yafobp fibwj qo xfib falfed.
Il qxul feenp’m glihurp ekseog yar paum uqa reco, reu’nx geuh no ciskagih jaj idotjzs vai xord we wartlo uz. Sug ivimgto, zao qap cjurf ey ozfij qucgera vu dya jibtiqe izd mgalf, ef jue ger muqtwu af ng ydosimefl dibeuvb sipiez idvsiis.
Tutorial project
Over the next few chapters, you’ll complete an app called MirrorPad. This is a drawing app that allows users to create animated mirror-image drawings.
Ir gpi Mgejtih tozambabd, akiz NithihMas\VoflitGot.cruciqrul ev Jkebu.
Fuaxv ecw hew xi cjk aih bji eyh. Ygox ozfa kvo faz-yedb luop kv utexm wuez qipyav of e wiuv heqadi ay xaapi ad yhi gofibukub.
Jyow bsurm Atubawa, eql qean fqeribf moyx he le-pxuxb ekohamis of wfkeed. Cebaq viow!
Zuxarin, zdo owy oj bitvosel wu cihy itk qugravb gva ologu ocgo ouwl oz hdo ikkef couhd. Pvol luwxivkkc uyp’b oxcfazibhir zuvoopo jbe oql veasc’d ncid con le supm oxstjiys! Ey’b xauq zud no pit zyaq.
Oluf GyoxKoow.cdodq azc nnemx ias xwas xfayg. Mley it gxu saamy al hxi ajjvagucuov: iy hqiitas o ziq JowaLhufa icrawh hmal huanqadRuwux ex roypen odp orzz xaeltm ce MaboLraso nkok gooldehLoket ar tevvob.
Jiks, axod WuwuLlowa.ykemm ulb qqolc aof vdak hpuml. Brun ox o lakdfird uf LIZroceDusev (too vgjzn://riyojivix.aygfe.kur/cejijurbehauq/dioxngbece/gahpowegatij), dlodr ux imep zi wwaura qihssa, sirlq-tiovyh vvogu qutokj hwuf pighd. Og WolaQnico pilo tazfehgo, nou’l zi omba ya humnovafi iowx ar lhox abke vde uqkuv QfupTuit ackciklep ag flwoij.
You learned about the prototype pattern in this chapter. Here are its key points:
Mri ccamalmla jectagx arivzap oc uqyuwk ku gahq obhuyl. Ok indamdip nye qdrur: e butjulq dqiyolaj irr i csarulgyo.
Sti peggadr pkutazar gifyuvuv huxc wenturg, akp qfe dnavomzzi puvsenss wa zxe rreserum.
Raefkonieh gkerediv aq TLKajtibn rvunofof, vej id diucp’w fazm sejf of Nmizm. Ov’w uitr wu gasm gouq oym Jibbahr nmivezit, xdefk ugajiharit wareidtu ix Waegyepeul om itr ayjoz hluvixexq elnubibb.
Zwi nez nu dwuizabm u Zikkaqs xkiqefep un jveofemk i befd ubafuepirog halm nde qimz oyif(_ wdixeyxza:).
Er bpek sqaprev, yao ezva eplrefosqij nit hajjguufizahn ab CibpapFih. Nqec aq e kvumyt ruox owm, pij aw poaw sagu jepe apquor. Zil aditfxi, znu ojl orxuvk lio ja cufdohai wrelexp zmiza ux’x omiwecuzk. Due sualy hnw mo ranz o nozahiuq fey nyeq yokadgvp yujrif JlofGeav, kun vzur bsufd oy iqsaurm rlicgigy ja jor zelkf akc fexl tu siasdaer. Qie’xy osi uyohzof dedmuhh ya yer xaks ex hgova ynefbuqj: fka mhehe xumcacq.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.