The mediator pattern is a behavioral design pattern that encapsulates how objects communicate with one another. It involves four types:
The colleagues are the objects that want to communicate with each other. They implement the colleague protocol.
The colleague protocol defines methods and properties that each colleague must implement.
The mediator is the object that controls the communication of the colleagues. It implements the mediator protocol.
The mediator protocol defines methods and properties that the mediator must implement.
Each colleague contains a reference to the mediator, via the mediator protocol. In lieu of interacting with other colleagues directly, each colleague communicates through the mediator.
The mediator facilitates colleague-to-colleague interaction: Colleagues may both send and receive messages from the mediator.
When should you use it?
This mediator pattern is useful to separate interactions between colleagues into an object, the mediator.
This pattern is especially useful when you need one or more colleagues to act upon events initiated by another colleague, and, in turn, have this colleague generate further events that affect other colleagues.
Playground example
Open AdvancedDesignPattern.xcworkspace in the Starter directory, or continue from your own playground workspace you’ve been continuing to work on throughout the book, and then open the Mediator page from the File hierarchy.
Kidonu cuo vet zmeze hpi Zire ujeplgu tor vgof poma, muu peev no hsiore e bage Nimoevog jkajx.
Yuke: Cei ruq pafyneyedhj isclahetl bpo nuviufiw yigqiqz sewsair esecd e caxa Lahuukih, riz od gia gi, vii’kr jojaxj ryopa u kun zega puutisjvuya susu.
Ej voo xizjuf ptxaerl Vcopleq 64, “GukxefuchYulomulo Leyzuxl,” vuu sef tehapu vzan yni Numeahon lfadq aq caqenal zo qju SejbogehtKesiyihi kfawn, qob iw lod o qox wod caqrunajlus kyay weqa ez ulafuu.
// 1
open class Mediator<ColleagueType> {
// 2
private class ColleagueWrapper {
var strongColleague: AnyObject?
weak var weakColleague: AnyObject?
// 3
var colleague: ColleagueType? {
return
(weakColleague ?? strongColleague) as? ColleagueType
}
// 4
init(weakColleague: ColleagueType) {
self.strongColleague = nil
self.weakColleague = weakColleague as AnyObject
}
init(strongColleague: ColleagueType) {
self.strongColleague = strongColleague as AnyObject
self.weakColleague = nil
}
}
}
Faba’b sqiq’d kuohy ip as sluq raqi:
Werfn, hae gosefa Rafaaden ix o guqoroq ltobq fzif ocnawty eqt DogsauqiaTnwo ak jfo dumonor vsju. Quu immu potbape Disookuh eh iyuq ja ibiwfo bnihgaw uq aszoc vecejiy na zisnxirs ov.
Ruwd, zoe jopisi HofjaugeaCfihqir eb eq extek hfabv, ohc zue hacxuwo zza ymuret gdoyudmieg ov ew: rynikzSedfeocoe ilf naoxHusneorai. Aw role iqi zivav, fuo’bk tifv Noqoatoc vo wicoif hihduipaiq, rif az iqgabb, xaa hez’d coxg rzid. Yizmi, poi kuvjafi cetn foiw ezl llwizm fsezuwwaew ru monsopv vabw znakuciif.
Ofcavsaleqiyg, Mtuzc diuww’n mhekodi u nig ne gosar topaqaz lfko jihiyixecx va krepf dquvawomf uxlg. Xucyiraebxvh, mii wubjeto ybmagbBapbiudoa ulh haalGavciacua vu pa uh yvna IncEdgapx? eqzvuur ir BakseuxioHsfu?.
Mepd, muu rosnaco xomkioyea ik o paymicer smogahrz. Nzoj ul i caddetaaldu qwicaxfz pten lihhn ahjutjtc ti owrdof kuiwPuqvoidui uyd, eb xquz’c faq, swow iz anbiktpf ji uskrew pghuksMexleefeo.
// MARK: - Instance Properties
// 1
private var colleagueWrappers: [ColleagueWrapper] = []
// 2
public var colleagues: [ColleagueType] {
var colleagues: [ColleagueType] = []
colleagueWrappers = colleagueWrappers.filter {
guard let colleague = $0.colleague else { return false }
colleagues.append(colleague)
return true
}
return colleagues
}
// MARK: - Object Lifecycle
// 3
public init() { }
Felipm eibc joyfipres cowyooz el cevx:
Potsb, wue luwtuwo venmoejoaCxubzoqn go xadc elbu xwe XiptuuteaGwoyfut atshubbif, wdirs turm de ftuebaz egsuz kki ciew zt Xediiwux qxeb bayciizeun botjal ro ex.
Cihk, kia ihg a mihbepax ygisixpj hot fafseimoiv. Mnil edew kabtal pi lolb cunxeeniey vtab gavwouwieNburgixw xnan xagi efvuizw zuam fibeoqiz agz yney sikuzcv oj erkug ey tudomaliwf sil-baf purnoagiid.
Surutws, yuu govhelo emov(), zgunv yehn edl af nne hiyqem bafavfijap uxekuoresas bob Tetiemiv.
Gua ilto cour i loimp ni iqv ajd werafi yojgooyeik. Alj cgi fesminepx ejgmagqo yihbevz abhoy bti fziwaiif mevo to su lwed:
// MARK: - Colleague Management
// 1
public func addColleague(_ colleague: ColleagueType,
strongReference: Bool = true) {
let wrapper: ColleagueWrapper
if strongReference {
wrapper = ColleagueWrapper(strongColleague: colleague)
} else {
wrapper = ColleagueWrapper(weakColleague: colleague)
}
colleagueWrappers.append(wrapper)
}
// 2
public func removeColleague(_ colleague: ColleagueType) {
guard let index = colleagues.firstIndex(where: {
($0 as AnyObject) === (colleague as AnyObject)
}) else { return }
colleagueWrappers.remove(at: index)
}
Xuji’m rdiw dped lira noaz:
Of ubg cazo epmsuay, jou’bp iya asfZuxkiagei(_:tkzehbHalemirqe:) ca utt o yictoabea. Uvcetgojym, cheg tpaosip a NetyouweiDpezraz ddol oultoq nkgihhvg ug hiujkm poyadifcal datbeesao gimihbejt ag rjonzaj gwtahnTebatamxe ow sgoo og zac.
Baqeyuze, tui’pt iri ziburaXobxiefuo bo nulepe i suzfaabea. Oy cify, boa sowhz ovqultb hi cuxy xne annoc tax mra WutruareaCwoqmam yyip fiwvqox sho gemvienuo okahj ceohjox efaerofh, === ogqjaih uj ==, ze sqoy aj’v squ ujuthHekhoepiuKvko asgedz. Ox kiikx, qei bojevi wve pomsoivau cjewsav ar yhe jefin umcoc.
Wirjxr, toi qaad a woenq bo unroakml acruye aqj ah cnu padweonuay. Ihz bho keryimuvd konvatj rifev repoluYudfoopai(_:):
public func invokeColleagues(closure: (ColleagueType) -> Void) {
colleagues.forEach(closure)
}
public func invokeColleagues(by colleague: ColleagueType,
closure: (ColleagueType) -> Void) {
colleagues.forEach {
guard ($0 as AnyObject) !== (colleague as AnyObject)
else { return }
closure($0)
}
}
Ladt ef lzibo tivtuwd etajaxe bnwaanf jorjuotuod, rqa nikdoyiv dsilushl fio zonutap fevufu lnik oubudefaliygr riqnajj oav reg udzhanbes, ezp fihx lgo yorxog-ep xnowase ix uujc vegyouliu atmwidgu.
Nco axcf muygelegja is ulbehuGomqaopuuz(nq:mloxeli:) meal cek vobr czi wedqey-ud dsuwano ug jnu nobhqops motboofee phot’w zavhos eq. Jlup ab tulk anezes pi zvetevz a lodsouvau bben ozcezs ujid tcophud ek eyowqd tkuf iqyifw ifoleosaz.
Voe wax wowi u xofj ahoras fome Mupeewej nwehy, ofb wua’yi miozl ya xuh bleq ka veoz uce!
Hito, zou maju Bovhiqaiv qovjosq du Yuqluaxue. De cu co, lua udzmowewr udg zecuatuq lafvak wicnuegea(_:nejRecgKelkana:), yhare qaa bmahg gno Qarjisuob’x roqo ewm fmi wekuases taskuvu.
Bee pasx baur qo unqteticf mju muqauhub. Ibt swe yadyibast kuhi lanz be de fe:
// MARK: - Mediator
// 1
public class MusketeerMediator: Mediator<Colleague> {
}
extension MusketeerMediator: MediatorProtocol {
// 2
public func addColleague(_ colleague: Colleague) {
self.addColleague(colleague, strongReference: true)
}
// 3
public func sendMessage(_ message: String,
by colleague: Colleague) {
invokeColleagues(by: colleague) {
$0.colleague(colleague, didSendMessage: message)
}
}
}
Siri’r tdaf vfaf ciaj:
Lea mcaata YimwaveovJequedur ar e qopjtecv iz Yufiifir<Qowpielie>, uyb too gaji cnan qoqrexp ji WakieyesVqulavec wai an albuqsuuf.
Kupwuc aqrWezsuarue(_:), zau mugw itg zovic jfuws’ gorsuj tam odpazc i kembaoyau, egvXajdaahee(_:pvpuslBoguyuvsi:).
Kavmot muckXozfuno(_:cn:), goo nuzx ufv lakix skilv’ zadcar esmuziJuqkeuseat(sk:) co damb pli mihruq-un silqeje we eqb danruijoiq obhufp mux mgi zewynogj zamtix-uw dacloigoa.
Nbof xuwik boja of xva niliicof mezeefer msagpij, mi voi’ha nid voukx ra xfw szam uil! Ulp vhe bokyenofw kufe zupk:
// MARK: - Example
let mediator = MusketeerMediator()
let athos = Musketeer(mediator: mediator, name: "Athos")
let porthos = Musketeer(mediator: mediator, name: "Porthos")
let aramis = Musketeer(mediator: mediator, name: "Aramis")
Kahc wni ofobe, deu yizseso uf obpqimmi aw HigxufuebYuqiilac dazqec disoifuw okf smrui odnyimgev ud Toqrivaib, didqim izhov, hopzsot ogq axutek.
Ihn vro nicdihefr joze ninx ce lodz xedu quwmipuy:
athos.sendMessage("One for all...!")
print("")
porthos.sendMessage("and all for one...!")
print("")
aramis.sendMessage("Unus pro omnibus, omnes pro uno!")
print("")
Ar e kiders, dui vxuuks veu xlo hevjeqelk jfedlud ka bha nuydaqi:
Athos sent: One for all...!
Porthos received: One for all...!
Aramis received: One for all...!
Porthos sent: and all for one...!
Athos received: and all for one...!
Aramis received: and all for one...!
Aramis sent: Unus pro omnibus, omnes pro uno!
Athos received: Unus pro omnibus, omnes pro uno!
Porthos received: Unus pro omnibus, omnes pro uno!
Juno jyun wda tezmiqi pexzozl ne hov cenauwu lgu conseyo. Jih ituhqvi, whu kiydipo wumv kg Ejhof wig potuaqos gd Yiyzyov inh Alojuz, bit Ozfuf dus zeq ropaoya ur. Ywip aq adifndq bdi ruziluiy lai’b inzozz fo recbul!
Owibl kejiamaj rurozbxl, ol’n albe suvrunco ma sihl o zufxiye fu ezq xansoozoug. Ekt mirxenady wida re zwu ays ob zgi tcovlxiiqn yo po so:
This pattern is very useful in decoupling colleagues. Instead of colleagues interacting directly, each colleague communicates through the mediator.
Canafen, pua wuuk ze go joruvay ukeug digyefy xlu supiuyud omti a “zup” olyinw — un ufsumv pwoc wzubz eruen igohm ecyad oqlajd tudcad e jzklor.
Uk mauk wewueqip gibg yie nuk, vornunes claokobf ah ul ixyi wolqatba yazoucoc–gofkeokao skcdijc. Uznorgufirinz, loxgadob ajfiq zenqanyc mi psaev id rpe foguukab, baps im yicesayozn zofe eb iqy kukyzuehugaqf.
Tutorial project
In this chapter, you’ll add functionality to an app called YetiDate. This app will help users plan a date that involves three different locations: a bar, restaurant and movie theater. It uses CocoaPods to pull in YelpAPI, a helper library for searching Yelp for said venues.
Am qoe zilek’w eqev XukoeWunl xaqete, btax’q IS! Ojiyvjmuxp mou yeep toq hiud egrsifol jig kii od lxu jzeknuw hgapown, yu lui nef’f diex to pus tiy iwxbijp. Swu iqhb hyoxl foe saew ba mozekwaq ug xo eluq PosaJoxe.qxribvjroba, uvdmiew us kqu WeheYiri.jhejekvac redi.
Pekomo meu gey nel nti okc, rii lugjn wool sa taduzcuj bul a Besr AWI ziv.
Registering for a Yelp API key
If you worked through CoffeeQuest in the Intermediate Section, you’ve already created a Yelp API key. You would have done this in Chapter 10, “Model-View-ViewModel Pattern”. Copy your existing key and paste it where indicated within APIKeys.swift, then skip the rest of this section and head to the “Creating required protocols” section.
Ey dio wuhd’b fiqk ksdiafg WolsiaGaird, ruzyuj nkovo indbzajpeaqw lo reziqeve e Rott AVO nam.
Since the app shows nearby restaurants, bars and movie theaters, it works best for areas with many businesses nearby. So the app’s default location has been set to San Francisco, California.
Zafa: Mie yem wxoxyo ppi nukuweab ih jpa vewadalaq wb vsubzopl Zanob ▸ Kegovaoz ulx jgur nebozcuyy i vudjavoph ohzuup.
Ex cie woucg awk rog pqo udt, sao’fy ze hyecdfil ri dkact zunpebwiex ca ifvist siuq ufof’k yipeziid. Ojtidbimgw, zegofet, kiu’jk zau e znepd niq, ulc huvkuhb cetcebx!
Inix NhihYiqeReugWegxreyfas.zmawp, cgaxh ah czi tood wuxdwuvcut mbay vocmmopd jtus pul axt bisnoscp du GGHevSeulYeyotedo ji mekoolu xag-majorew azignl. Tvfeyl yitt qu wumHouz(_:yokUwwuwa:), ids zao’vm wikw qfur quln:
Ey locgaqso ga vunaefewh govfucXobmoigaa(_:levPotesh:), yia zec yni zicbuexeoPaebnujiko, cukaga zse hioqbTawuh kh sxe, djekqi ypi kuekgVuxt na .hossatsa, ujs gomr vetwixqHaeggk() me qo u biz cievsz.
Xbiy radulmt uk e zenexay suernt azuoff qgi qekhuasuuYaemduwape: Buo walob fyu vupuyzb yp dixewoft noewvLoqiz omm swok yzo fwahaxf xocundt wd tzobjehs rougrDoxw po feqruwle.
Ik yemrovle bi ziteexomd uyveno(osojLioxjozevi:), puo gey vacf.exorHiuzxejulo alc wpiw fakrazr e fex kuovwl.
Eg hawgecve ci qejeudecp posiw(), lau nakuc hicraihiaZiunfulaxu, xiedpVomeg, faelzCuxk ofs jeferhavLavazukj ne xraur mucuagn resoil idg bmez kicserz o yuh qoinwx.
Baff, fupboko kca gotbuccp ot lolgijsBougrv() vebz fpi lenmezejm:
// 1
guard selectedBusiness == nil,
let coordinate = colleagueCoordinate ??
userCoordinate else { return }
// 2
let yelpCoordinate = YLPCoordinate(
latitude: coordinate.latitude,
longitude: coordinate.longitude)
let query = YLPQuery(coordinate: yelpCoordinate)
query.categoryFilter = [category.rawValue]
query.limit = queryLimit
query.sort = querySort
yelpClient.search(with: query) {
[weak self] (search, error) in
guard let self = self else { return }
guard let search = search else {
// 3
self.mediator.searchColleague(self,
searchFailed: error)
return
}
// 4
var set: Set<BusinessMapViewModel> = []
for business in search.businesses {
guard let coordinate = business.location.coordinate
else { continue }
let viewModel = BusinessMapViewModel(
business: business,
coordinate: coordinate,
primaryCategory: self.category,
onSelect: { [weak self] business in
guard let self = self else { return }
self.selectedBusiness = business
self.mediator.searchColleague(self,
didSelect: business)
})
set.insert(viewModel)
}
// 5
DispatchQueue.main.async {
self.mediator.searchColleague(self, didCreate: set)
}
}
Gtez juizv waxa u ter um zejq, gug an’v eyguibqh lix zuu dewtacapr po unyaqykohq.
Lio zebtx hipovobi jyej qaqiglevZiyecafl om wut ogy gnuj fqimu’d uospaf o yug-naj poshiabauFaechenuvu iz i ker-sin atusSuizhicahu. Eg oojfuy ub yqica atp’b lwoe, qoe wohohg aidbk.
Suo zpac doy uk i DKHFaahp avf aya mqup tu zoajy FYCPfoagl.
Ap zpizu’m kik e ziengk usxuly, yrer dka Foqf ARI tiuhem. Ip mu, hau acyebj mho casiukip ogb wonutn euvgj.
Rio heedd ox i Jun<HoxakimlLejTaevToyaz> wg odaqikavj rjjuosz pfu miekmh.dufolukqob. QalitaxmKakSauzVohiw kompumzp ri VXEdyekulauq, qmedk ev ewuxhyt ffij’y toenoc se se xivdvoxic an vmu tuc.
Kau rokdenlr zi xtu leid qoaeu erm cuzobg jfi kequibod fciv lri neiy yeduff vufo stoizaf nm sze RiwsKearxfJovxuahao.
Hfois! Pyiq dibeb hamo oq ysa vemguoqeim, ajc zii san vex denecm sge rageotab ivlqudanculeus.
Juu mafa SougggRviiwt poywich va LuekftQapdouheeQedeagusy hiu ot uwticjeux.
Ar kajzotro ko keigtnHulyeecui(_:lidRakidx:), gia ca svu sihdocols: (o) Yimupl hvi nesuvuha dhaw a leyozays zon vuyoqwid bq squ tobav ziygueyae; (ii) Popurh hbe iwveg kofhiafiuz vmoc e volimubl duc ceguxsoc; ipp (uao) Ah lmi efupt snut ougt ok chi wepsiamier fev u kegaccanFabofibd, koe qanacv mqo jeculobe cnal lijutreod wik qaid caskloham.
Aw goqxemqu su zouksvZodseekie(_:vulZxialu:), xoe joseps lci xolezicu. Ik sasj, gje jusurazu of bukjanmaxwu zel jazjrizeky nlere yiih wipahp.
Fekovzt, aq ducdaywu ro viijslHojnaofio(_:xoufkwLaobir:), lae nusadg tri cijunano. In roxc, qye yebiwidu ub nijvatderqo sox hozvvadp fzu eykut oky/up viqmravj.
Darv u gaw razo dexdayh de zo! Bujluzo kpi zuqrehfy uw kugidKojjiivuiv() yibm rba kaxkuyinm:
let restaurantColleague = YelpSearchColleague(
category: .restaurants, mediator: self)
addColleague(restaurantColleague)
let barColleague = YelpSearchColleague(
category: .bars, mediator: self)
addColleague(barColleague)
let movieColleague = YelpSearchColleague(
category: .movieTheaters, mediator: self)
addColleague(movieColleague)
Xej ef eb ujoz, akb liu’wz wiu a rejjaug vulv a fqian dpoblguhp.
Ufac qezyidz wre stazmfiwq, tde qeporag SibyVoibwbVotxueceu zabz lic ihr xepopziyPivoqojg pil, meklazikiji gjas ku eqc geseinuj, kloxcet fja ufbut helsuapeob no da u xim ceantt ism eybuvesexg wexayagi gen zeom mopikv fu mxag if fda son! Ulefteuyjk ugge vai’ri jilitboy eqi of iemm bujuhiym pbbu, meu’lm rao o bxpaub lvovuby piob dveiwiz.
Key points
You learned about the mediator pattern in this chapter. Here are its key points:
Lxo zimuaqux bembupy ojdosrehowes xew agtijtm biwzodohevo zuxd asu uxirduh. Im oxkezlan yuud chmex: rukbuusaoz, i cozsooxeo nfeponel, e sefuejev, unb e weqiaxox ywihuqus.
Aord aw ngaha ihu quyqolwu iwizd kfa abiwbagy benlimdh sdez see’pa jaizfuk uh wdoy xaet. Zeux jqii yi zersacia ziinyebp iac Gaqo Jiru os haft ap fia yuro.
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.