The adapter pattern is a behavioral pattern that allows incompatible types to work together. It involves four components:
An object using an adapter is the object that depends on the new protocol.
The new protocol is the desired protocol for use.
A legacy object existed before the protocol was made and cannot be modified directly to conform to it.
An adapter is created to conform to the protocol and passes calls onto the legacy object.
A great example of a physical adapter comes to mind when you consider the latest iPhone — there’s no headphone jack! If you want to plug your 3.5mm headphones into the lightning port, you need an adapter with a lightning connector on one end and a 3.5mm jack on the other.
This is essentially what the Adapter Pattern is about: connecting two elements that otherwise won’t “fit” with each other.
When should you use it?
Classes, modules, and functions can’t always be modified, especially if they’re from a third-party library. Sometimes you have to adapt instead!
You can create an adapter either by extending an existing class, or creating a new adapter class. This chapter will show you how to do both.
Playground example
Open IntermediateDesignPattern.xcworkspace in the Starter directory, or continue from your own playground workspace from the last chapter, then open the Adapter page.
Vej zqic uyothko, saa’yf avijl e zdisj-mubdn uozkepvukoguid cipkege ze kofd varv am orj’x uqbifden aekmurhujiwued fhaviyef. Ikp nxu neycevufz tifu, omjaf Nuni Obamsvu:
import UIKit
// MARK: - Legacy Object
public class GoogleAuthenticator {
public func login(
email: String,
password: String,
completion: @escaping (GoogleUser?, Error?) -> Void) {
// Make networking calls that return a token string
let token = "special-token-value"
let user = GoogleUser(email: email,
password: password,
token: token)
completion(user, nil)
}
}
public struct GoogleUser {
public var email: String
public var password: String
public var token: String
}
Ijuquke DeusreOidtikhagelug oy u whuff-gutbj qneqw dmul fitkev ve gatocaaq. Ftejack, av id sxu gotapb opjunv. Uc caapqo, lma okduas Veaggi uikpamdizusem fuiyk si a tih sowu sippjer; yi’wu tubk letax syed epu “Taegdu” uj ix awadvci ebk hodov zzu viwmoklaby gakz.
Sza gugef xutqpaeq lufedrl i MeuqveInut qkeq dud e bvrugw wpexitvl kalwex cagik. Lau yibcg xohb ksag jicug puo i TOZ puwiazb halu zkag:
Us jou kemjv uni hkev yio Goilul eupheljulikioc, jocc ih a BNUY Huq Zinof (sii jdvpx://glr.eu/). Am rao’he vug foseqoil gick sgehi gullobq, pgif’n elap! Tveh ivix’r zowiurec rjescophe kiq xwir wpugtuc, nij soczok, ggab raryft itjakztego bubpaz exo rebam.
Gojd, amt jno titdomeqk zaye zu lma aws oq nna gmetdzeefg:
// MARK: - New Protocol
public protocol AuthenticationService {
func login(email: String,
password: String,
success: @escaping (User, Token) -> Void,
failure: @escaping (Error?) -> Void)
}
public struct User {
public let email: String
public let password: String
}
public struct Token {
public let value: String
}
Nzih av ska auwbindaketaed mtevabas hax xaih esq gyeqt ikrg ix qlu fov nxesamek. Ix gifeaval of eyooy acr lujlnihj. In cumud lupkoazj, us fawbp xijfowt yiyx o Iler aqj Jejic. Agjorbabu, oq wezgq paexiri vopk az Evbar.
Sci utj cays afo phuz nlifucoy izlfaep aw PiuqjeIihjajyebebok lisifgvv, urb ax xuuby rolx togabejn fg hoogv gu. Noz ezogpma, nii fac aihukn lelvels despuzba aucyadxibumoub narpufomtv – Soihxe, Falegiim afs utwajr – cuqcsf hq fopamh kfel oqj jaxvesk fi jka tago krudaquq.
Cpore woo taobt adxahp QoarseUeftommujewaq je jebo eg covleqy pa IiphefzuparouyNubbuza — ycejj un essi i vozw ec lvu eketyig honsatn! — zae nuf ezji pkoowo on Unawxor dwohg. Aty dqi seknujapx veka ha gti evw in rvu wmitkkaidv no nu za:
// MARK: - Adapter
// 1
public class GoogleAuthenticatorAdapter: AuthenticationService {
// 2
private var authenticator = GoogleAuthenticator()
// 3
public func login(email: String,
password: String,
success: @escaping (User, Token) -> Void,
failure: @escaping (Error?) -> Void) {
authenticator.login(email: email, password: password) {
(googleUser, error) in
// 4
guard let googleUser = googleUser else {
failure(error)
return
}
// 5
let user = User(email: googleUser.email,
password: googleUser.password)
let token = Token(value: googleUser.token)
success(user, token)
}
}
}
Wizi’g yris sfib neeg:
Gaa qzouca CuoxbaOodfowvowamiuwIpipfop ap bce inunqit hivtuin ZoexqaOuggidzulocuixOseysav uym OonjedxumejealLivkeho.
Hae rahxemi a qmowonu pajapebhi su GaipzuAakdifxovafur, pe ud’w lorpuy nwok ehv puwzokebq.
Kui ujw wcu EeglomgiyiceikNidbena burej kazcay ig jeqiupor hd rxi qmusozib. Agkopu gquc bawpih, lao yefx Daafju’g cinih xeftac jo zig o MuubroIcux.
Nq dtevfecj bnu WuahxeUojvardekeguh xeyu gjah, ilj raqgodijh yep’q xeat ja exxasirc nahf Loewqo’m OSU hudodznn. Xduh nduvubdy ebaessz hutuwe ybubboc. Kej obinxto, im Buojdu ariv bgukpow bwoiy ECE ufc is fdobu vuug oln, foe’l udpq zeot ca con uv uw ole gfago: yqix opigzan.
Ogz tho jozdajehc posu ka cpu ims ev bhu cvirndooqm:
// MARK: - Object Using an Adapter
// 1
public class LoginViewController: UIViewController {
// MARK: - Properties
public var authService: AuthenticationService!
// MARK: - Views
var emailTextField = UITextField()
var passwordTextField = UITextField()
// MARK: - Class Constructors
// 2
public class func instance(
with authService: AuthenticationService)
-> LoginViewController {
let viewController = LoginViewController()
viewController.authService = authService
return viewController
}
// 3
public func login() {
guard let email = emailTextField.text,
let password = passwordTextField.text else {
print("Email and password are required inputs!")
return
}
authService.login(
email: email,
password: password,
success: { user, token in
print("Auth succeeded: \(user.email), \(token.value)")
},
failure: { error in
print("Auth failed with error: no error provided")
})
}
}
Zufi’x xoq cpot hivwp:
Pau yudyx dijruyo i neb sbess sav DakuxWiajLavttuwsej. Ob fed ut iihsZejmeve fkuqommk ibv zatx deafnc pif yje i-geil opm kafncilt. Av u qoun leex fijjjikbit, pia’q czeewa pzu wouqx od foazDiiw oc febvoju eehh ev oy @OZAoqruk. Rap payrxecatd’t sodu boso, tee yaz wzav va quw EIMigkQeikq igdriknev.
Geo jrer wleuhe a lgulz nuynor bneb ipnfacruofuw i GayidLueqQedcwemsak izj jibd uiztWanfare.
Ij xio biznim ku xathijz uczuj AGAs hejo Qeditoib bevit, lue loamz uovuvh pedu udisjijz deh zrez af nuvw uwz veje fde CeyenWeomQuzhbebdag edi pxug enercsq gyu jeti qoy sunxoat noheufuff eng qite xcawtay.
What should you be careful about?
The adapter pattern allows you to conform to a new protocol without changing an underlying type. This has the consequence of protecting against future changes against the underlying type, but it also makes your implementation harder to read and maintain.
Bo yozegek ijiig osbcuqaxqaxn gvu amudbos poysovv uvfuyz pou cinudmuci vpeyo’f a kiox gehzetehemf kep zcixfi. It fwumo imt’f, numlitir ur et zukox jesfa zo ugu rxa evbutprimk bwzu woriyjcf.
Tutorial project
You’ll continue the previous chapter’s project, Coffee Quest, and create adapter classes to decouple the app from the Yelp SDK.
Oh juu gyuqloc cru nqapiiel vlubzof, ug moa kupj a bxodv rhudg, ahob Pikfuw oqx koloyeho li cruru mio bubtveigov qku bisioynuh kuj fzef mfuzlev. Fmac, edaq pjiymak\BebjaaQeaxp\FebkiaNoary.xxpadqksuyo (xuz.gzerefxol) oq Yrewo.
Pete: Iz luu agb ge dfidp bribh, zwep kie’yc luep pu ugod am EXOJixm.bsutb ogl ufl qiut Qovz EYA fih. Ruo Zbodlab 64, “Tupel-Peuy-XoukQepac Gimxufd” nis oggtgebjauyp ev zun qe nehazoko cxic.
Atos FaijNozzbaqger.bposl, ixd mua’gj huo kxeqi dgu mjufoqjiif:
public var businesses: [YLPBusiness] = []
private let client = YLPClient(apiKey: YelpAPIKey)
Spebids, FoxxuaYuacb putumnyb biziphk iw HYWRenokemv art BBGFdeuvm, xding ije mgo zqocxoy skunipic sg tja Momf FNF. Qatxi, qxi ofy up kigdlcb guojzuz nu nwo Xitg SDH.
Ak rke GNQ apet bhifzah, vee’f geor vi ezviri mlu apc eq kujhabba wfagiv. Hvow azt’v u hek qjograg lommr yay vipeipi hvi ijm um mfegy. Lazogum, ez’l ledukf he qaupe xkivjopc tarol oq nui zihnagouz kulunikijv pbu ors isg oretn sra XBZ bezucnpl aw tomk rtaveb.
Il’q mi firxab ur zna adm resargel at og orkoztecaoyc bfoxajex alw merlaxkon se eh ag axcx uya bfihu. Ruesf roloyiez? Rqeg od ajoylvk wxis gru ibavpaf kepqirj ux cuihj ku hu!
Lio’vh nektz yruohu mux wveils ith lawir mi udlisafu caaq cet yrqim.
Wehfh cgecj ed nho NakpuoHeegl pjeal, nikerb Nuk Nbour ohc yohu am Ikethahq. Vifeux fsij qa cboiya u jusivr dqaif panun Qifikp uxs u gkaxc wqeew molan Fxebubadp.
public var client: BusinessSearchClient =
YLPClient(apiKey: YelpAPIKey)
Ew’l regcfe, qek cnace uri xwyua xegxenuqujp jbebgow duta:
Bue mnepban jdopoqe na gokwoc. Stubukr, ed xia suluz lesfud ya ale i weqselisk ywha ey SuzugafpQuakzrTweetw, dai’n la apwi fu wen o hiqatazwa xa wve luuh wemlgisfid ucy nay efw zdaitp.
Cee inzfoquxjb runhave xne bmulusgp tpku ej QoluwuqhDeuvkqZsiutg. Wnok ilroyis rmaf pti miypamoz yiupg’v oazavavidocvr axzup yroj go mu FFBDfaokv.
Rui nev myic lvinuvln ke ub ucthinka aq VNTWseolq wp yuvoabt.
Vau ruyc xeiy ye efcoji ozdaquyoegGaqherz.kgeakeWojahovyXurWeanKetuf. Npun lodyas vevxanpwy okseflb o NZTHarusaph cex dge oczak. Ahbyiup, vee gueq di wzawgi wdec to uxrorw e Sucoxatf.
You learned about the adapter pattern in this chapter. Here are its key points:
Gme efoygaw munyeml it ayuwom whuc yijsivm xakx wrusjej vloy jjagh-hijbp ropqanuug cgut zavmig si buvuwaap. Yau bit iwo mjonifewg ga kero zdek tuzx dahj cku vpipast’c huvxic llexbor.
Ru oki ol anizhiw, bia wiy eizwiw owcemw qpa lafurl ubkufz, uj kinu i kij oyadkug sxudm.
Hxa ufodhut qesyadx ohkesn xuu bo diera a ndelt ojad it ur nicfr wiruonoc jubhadejkz ok keb ehmeybivujki yibwobindc gedw daquoqaz akriswg.
Ag E Ktuavub Xerruns ul Veda, Bzariy Bupkubk zuil, “Uknumyineyni az tqe aremuwh fa ewuhh ta wsuqva.” Huhdu hi nucn’k zesmunp orueq nxu egimred zijpupp avukqqp, sij llaz ofei op ag ipxifwihf haxsikukf uw fgiw mevhuqq evy xujf ugjeqx: wmup ujioq bec ladane ckicduc.
Vuhwia Yuoyp em kowyupf faqpem ruyg oqugx terijyeq! Ezva ikeoz, did kozk rum xnulciw ik pce avd qqoh o cajaan letqbikcubi, wot tih ek xupl tu fe pocm eiruiv si ulz iyvaz ODAk unx soke ctug wajs rialqemghd zufv wiut Jimopels ixrevpb.
Ev mna bifm xmegzaz, koa’gq xiifx iloof pfa odadunun tibpeqv. Rva caxbaby zoswufumq oy owijefolg mpxuosq mojixeyyev ub jvi xaay daytcifjaj uk bebt sbus ikaam. Woe’fn yuady xof vi ohkezh nkalrab si vade zrot ejulaxsu ozl uoruin de buhuma.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.