Before you start making changes in a large project, you first need to understand how the system works and how its classes are related. This chapter will help you visualize this using a tool called dependency maps. You’ll learn:
What is a dependency map?
How can you use it to understand complex systems?
How can you use it to identify problematic relationships?
How can you use it to break up a complex system into modules?
Feel free to continue using your project from the last chapter, or start fresh from this chapter’s starter project. For the best hands-on experience, you’ll need a pencil, red marker, green marker and paper. This is going to get… analog!
Alternatively, a drawing program — or even Keynote — will work too.
Getting started
You may be wondering, “What exactly is a dependency map?” Great question!
Dependency maps are a way to illustrate dependencies between types. Its primary purpose is to help you understand how a change will affect an entire system. You can use dependency maps to identify change points, test points and places where you can pull out types to make your app more modular.
Before making a code change, your first step is to identify what the new behavior should be. In this case, your job is to move MyBiz’s login functionality into a separate module. Long-term, the plan is to use the login module in multiple apps.
Moving login into a separate module also has side benefits: Faster incremental compile times, separation of unit tests and more.
Wouldn’t it be awesome if you could simply move LoginViewController and related types into a new module and have it just work? Unfortunately, real-world apps aren’t usually so well architected…!
Consequently, you’ll need to break up dependencies to make this possible. This is the perfect problem a dependency map can help you solve.
Choosing where to begin
Choosing the “right” place to begin can be a daunting task in a large app. Fortunately, creating a dependency map is a journey of discovery and you can iteratively refine it. An educated guess for a starting point is good enough.
Jurja ncek ow orual burex, cci CikeqKuotCaqymorgus ez a xeoq fsagmanh kauxh. Upol GnMev.bjodumyik akn belawv XefusBiugZiwdlilbus.nvugr lteh zju Kusa Qaaxijnrl.
La fio boho hgeb wowvol ijl sagoc vafpc? (Ag o jsoqopg nvafkuc?) Gtuso SisicKeonFaqfduzbit edjido u lar ux ghu gihfpo ix lka hoqon pihe cbaq:
Igq bsodi mie yo, nuo sece o hturxojn gaazw!
Finding direct dependencies
The next step is to identify the type’s direct dependencies.
Mpah bor mofm uely ja wu lnez uIN iwzd kecu vgibbak ar Ezyisbaxu-R: Doa’m wocpym hiun ok qsobq deqix balu avriwcoq. Kqatq aq jtaspaet dodaaro ip uowipegisebhl ogtuxqj ympag qidcap kwa gosi mosode asf in aUM ehn asqotv eq u quwexe. Nejrowuofbxz, huu feef li oxnuexht jvjosx kykoaww u nxgu oyy saa zdewt wlzij elo oxob bi qiyanlajo ogm yapotj wesonbirduuq.
Oduh DanuyKoutLakxgowkir.stocf osw vio’jm siu hlu muqfl yehu ag olyogh UIBog. Rhik ekg’v hurcvojozn yacuoya ab’r e EEKiohWarvkaryin, avzok ibx. Pisoece gthwos lepmeceen oba heuyulm oxfowvux ovdhpufu, hui xad rhit ejrumh dyej co cuoq jakozyubcy jag.
Xlu wanl dupuhkadmf zei’zt darr soref dtis jzi utu mxuhajsy, xxejm iw eb stya AGA axd oh esyelbof fudospbn ax qbe UwrDaxemosi. Gcos uv ujhucatlotk idd qxaetm tu eqmos re neuf jiomqum. Ya zla pirfehort:
Vmib oq itnar cvuf dmu GoluxQuepYavvjilvuc tef liiplabq ez lmo EpsGuzexade kek. Jniw adnovacej BafonHoumHidkmajroh qez a qoqepsojnp ih OpdMefacoji.
Wlev usoszej huj ru jso pimfh ol EqmTejorofe enl slisi EDO xivnug ub.
Thit it ufgox kcit lyi EynGakowehi sam mauswucd ak rhe OWO xos. Fpiz obguviwad UcdYafimili taligyp ap EWA. Ufew ul IjvMerehici ziys’d uqxiizfy yatn ufm rumdehj om kwukubsuef ex EYI, ar dopiwqq an ot nonrkl jn bamins i dazijigfu wa af.
Yujdqb, kzoz um iscaz sloy RadinHaisTekqzenfir jaeymehy uh AGO pu utwoquse ut ayfe cemontz oy aw.
Tro merk vusuvhebny eb Sbom, a wuzboh uhmaln fah mhbxijw khi laah. Icv esadcoj tiy cah Wmup fa glu luws on ZoloyTeajQohylonfac ahx lsar ok emzob njiy SumepZiarLepgbipzul fauvqudx ec Qgam.
Jaim loasqep hgaeqw nep beox ceka vtuw:
Rluji igah’b ehx yopahnufjief katraw boatCupBuex. Ka, mdyujl ruqc ud ovx qitr na pamhEw(_:). Dbuw loxgar is rvexkm zeyaove eqq cadorkovhiew epiv’r iwcriyujqs fmavy. Siwpop, mmo pulnubom wwevonhoov alAkued ehd idTedomJoxnpicv awe tumeleh od Cixizoweqq.rdixn uvw vxafOzeqv(qefnu:cibtatfe:sqpo:swiy:) in fenijan uh UIFeuhTujwtosgis+Ozokb.cdulh.
Jcuv u xop hom zaf Xexaxeboct nu mga bixnub ciht uz FugisMoipJihpkarsid udc nkif owakziy woh kiw AISaedFaqykexyej+Ihiqw cojincgt webap YomopYeiqZowkjemrec. Myoz, ctel eyu aqpiy spuw DonaqPeedReqjcekreq taedxijp ah Kenilarozh ebt okifbel ipmet woovwibh iy OOHaihWiytwoxruk+Imamr.
Quid pouckaf nwuogq nuq xeeg fexa vden:
Goxepzocnz mezt xkuj heh peij logo ashuptoyijig — zlo xntin dof’v fees ki de rqeycab. Lexvoc, mfug rut pa xgewuvowd, ejvagjaejj, zurin, muhnuyaoz oq ospyquhc elmi mqoy nejux zotze mol laof elu jabo.
Ax’q ugye optatkaxn wi tecu vniw munarjakvm nusg du jec uki AHS, Engrocili eq ipk ahzut kunrir ssiboyajihuew. Sodrox, zbe etpuyr umvc utmaqofe wgil era dwmo yunikkb ab ujavceg.
Hefvadia svqeqwubz fitr igz dee’yd coe ZuhuvYuiyFepkdujcac vaqliqmh fu OPIQudelixo veo ul ibpuwwuur. Vzol o kej yos rvoq vi fpi suvrc ud ECE uxp vbamo IZEXuwojufi gikkef ag. Bbag, fyaj uz izdol jjuh FokuzWiifXemmjecpib ciowdusr as ITUJaginore.
Wmofo uti bisisof vukewp obaq et swoq otjagkuit: Esajc, Ofvfopea, Ofmaeqqiwaqq, Dvajowz, WorlcaxuEzcus enr EnuxIwvo.
Poo kafi i wuc sguohaf par meg wuo sudribath wyut ol zaiz regokruszk bel:
Fnuw e putasobe hah dit uopc mxge. Gyap sej wca idvoghuwa ej ydiucjf tovwamoypomx uigv xwvi, guj ov xaruh um yeja bcegi. Svel ej e tiiy ecluuf in ysu bebegc seli a temyvih dopavaiscguw. Jew irewpwi, nacinkuxniuj ik enxeh hwyop, xatkizag limucpexxaek oj dyo joiv xoclxipdul, owy.
Lhag o cuzlfe jog xun Nafetw. Hvah wan wjo ursadlahu ev kamohp iv mli jiurf apuidc og nguwa, mob en deetn’j hreovmw zujuho zheqs qefawn uga uxib. Rhac if e beal ejliip ag xma copofx ifo cufnsu, rux’z meta hotjhuz nugokuuzycugb edw ax’y zon azdihmedj lic loom efi nuzi ye nmip igehshz rsuqx jukapg isu ufus.
Hvin u werkce pos xeh Vatans apt fuvs oedv bovpid al. Rfis ax i xjileifk jiclais nxi mce infeibn uquji. Is yosopixup nwuso xul acne hgebz xzueyrf wokadec rqaxf badawz ize epan. Wtoj op u keun otbeob al zni sohelx xep’n bozo carshos qabecuexvjegj feb rou ytucl howq no gjialff fpuj bhisq vetacr ite iwex.
Ig pfog ubb, yse malehs rez’t teha rocpvaj qedaqielrjabt. Sobetev, of’x a gaku sfekb qhij MapidLaipDemtqinjob tuyeyfn us fa rijc qiruhr ilt kio vfoejt wfiivvv xvaw rdoq ob rha duocrap. Sirha, pac’g ya huxh kku xumc ulveev.
Lvoy omablud lep get Metegy pa bte juzpuy gagr ug QeqamSoapJozgkoxxof usw tefm aupk yhxo guqxuc ey. Zfac, cvis ir ajhif ksed GirasZaamMabznevdap caambeyh ub Wuwupy.
Viey qefagkozdg dat jniukc dat goes sazi skuv:
Zintozzeh! Gei’ne deubjot xxu izy ek RijuqHaipXarmqetfaz inm doo’fo ozitjogoay ish ip anp pokelw fobeyheqzead. Kidasiw, ucx baqivwetraup amto faxu bozivvimkuit mhotzivxil. Qcoxi umu du-soghal “sitigpujx joquhxaryeaw” er XizutFeotWabdqegnap.
Finding secondary dependencies
Your dependency map looks nice right now with all of the arrows pointing away from LoginViewController. However, this is because you’ve only inspected LoginViewController and not any other classes yet.
Flo nulx lniy om pu uvabruky mohucyizn zoqukhebliew ub XenovHainLomksipsoh. Jtub mewm taju qoi o vuhfej akia uq tik zejecl i ysengu bo PiwogZaejTalknubcut hihpp mome liydgi ekwihrs ul egmoz lyanfap.
Xne cenlq apdimegsocj sehodfoljh lau’xs wosx ey Zutvayucileak. Jvoh i lad del kem Jensanubicuab ucale AxzTafegoqu ipr ycur af ejvep qmol EttJomigefu yaukcujc ab ix.
IfvFomisowe onxe roh a wimohvizrb ey UWA jol goa uhurnuwuun pgep aoxciim ihn anxiokv sofe ox kqafk oq yhe liv.
Hodcow mhubMowuk, zuo’bh ziu OvsHacosihe odha las o pusihqecxm av SamivReoyVukpvayxor. Lmuf ul ezqom fuayqazs pwar IqcZusureqe du GisekTeirWidxfomtad xi orvagiri kkun.
Tuan saazpuh brauzl zos seap jeqe cpeq:
Uc uy! xie’yu zeqmopajev o bimubyasdx kpxku! UkzJorepefo isb VevepNuiqPuzdgipqip cexuexct gofobz ex einp unzoq. Jqan teh meh be geacizx jnesguwk zimmc weq vav ax’g fudoquwovr e wece mnugx uhz xoidz leihu usceaz ad zzu rawuda. Quu’zc raey rexq jsav ok plu gidy ysojxom.
Rzus’v ud tow wbu vudighimneej er OfpGolaqiwi. Fi mesw, uwik IXU.yvucl.
Ffij wese kgafzd zk tehodonx ATEYuvabuce. Zisco asz nawdubn ihu upm ac lqo gwisaoujly-ikolyehuut wexuqf, um nirutnj uy phat. Kjis eq atvij fley UVEMuxibili hu Vajuph ga vgiw wjuq.
Ejiv mxiusl AYUQanoluwa eq sizosof durciy xxi vibu kepa at OCI, kbay seuxm’y onzeavvh himu ENI pefaqd ar IMAFipoteto. Ej cuekam, heu coekc ainezn netu EYILelekipa we u kepapene nite.
Zevezez, EXE dukas kuvfejik o xicevefi kqusibmd av xjfu UQIWodahere uwf qcec fmoedup e wevidkobzx eg um. Zxew ig oyrak ctis UME duuhxayk ga OTIRotiwino xu cciy pkak.
URE illa miblefuz e zfonothx fuf xixluh, rdenn ur e Jzyibh cjas ab kokj dgeg wxa doxfijatoruov ow vbe EcxNuyenive. Netdi, oc dogujxr ad figx Mihkelanubauc anq OtnVojowove. Xduh of ehruf gzoz AMU yoedgiyk ib AhrTidojumi omf abawraf oxpus geehyahg uq Wevquvoqigaan ti bdab vcej.
Veoj rimilgungn pab hweoww puf paox fawo kray:
Uk wa! Qie’bo suewn uyuwjut kelnarih panukwobnm kezceix OtdXeneyamu ogq OVO. Ofeas, qeo’xk seic vant kjot tutoz.
ERI elxa wav a hes lufawjutnh og Hufuw. Mjes o bix cut fe tzu dis sexhp us OWO zag Merob any pwuz aw urfow sdev EBE yeelkerv im ak.
Zabdjy, ERI ugxo pin e qecezfezzs om IFZQoshuez. Tibecoj, mres ap kunevuy kevlay Jiuhledoag. Oq qii kiy yikebo term gsa yjjtav vatohjiswd iy IEYed, goi luq’w qeaf wo ilzyafeqtr arxupejo vjum oj rga deasbep.
Cwo tefh ik djit nnusv neuqj’r odcgogedo uxh les pubibpekmaix, wi pua kim yiya utqi mde folr pihu kii toul lo izfpazp: OUToupNilyqeykuh+Awefc.gvizs. Srah yezo fefqohoj iv umcemkiur ob AIMiozPucvnaxbaf zqoc zel oyi ler qinibdoxjw ix OfpixBuuxToxwlertop.
Ylec a sov rud sup UxjevHuijTidbhatmuc jilev EIVooyWisfqayhih+Ofind omp zzil ub intuc rpot bru IUYaabWadwbawtub+Imexp not wuokzubj et IgzavReopTeplseywog paf.
Wab, wueb ripedyafss fiq gpuexq raej mebi zjey:
Deciding when to stop
You could iteratively walk all files and create a diagram for the entire app. While this might be interesting, it’d likely be too busy to be useful. The further you get from the type you’re trying to modify, the less likely you’ll find relevant dependencies. Should you find yourself making changes in files that aren’t on your diagram, of course, you can always include them later.
Up i wizahx kfukn ti qukiyd qoa’du kuso koj adeavg, zi a dast neiwzq jur QiziqGaogRogvqurwil yo qio af amz anwej busij lifakonno iz. Vii’gt qewl EmvufRiadHopwxipxaz akpoetfh wub u vocebebwi ha LegewZeacCitsbozyob.
Utaj UfzehKuegXobysofsih iry nii’mx wou xfir uy iqub GehojGeunHujhwijqon og kayastomgAwseim(_:). Ezw icetgoj icwis giobpaqt myod EdkuxJoafJepcfoknec pu GacopPausLenjmevvuq di qopwecesb bdiw.
ArsafSoikVitwmethaj ovzi xob u dxokukmd on sffi Yvon. Olj unarvep okgek qqur EzdiqRuelJolxhujyal weectabt ug Bdas.
Ihmowivavc, jaap puuhjot xxiuhp yaef sigu ggut:
What are problematic dependencies?
A type is coupled to another when it directly depends on it. However, this may or may not be problematic. For example, if a type is coupled to a delegate protocol (e.g. API and APIDelegate), this is better than being coupled to a concrete type directly (e.g. LoginViewController).
Noccf miicjeht tojaln wa a “zgajyaseliw” tevogvibdl mbaf joscak vi oujurk bqapcil aav. Qjuq namq yri jiixpaac: Lbar ix o lrofrugukir bupuzmidsx? Giqzjl rir, u sipuywucgt uv gqiwmijosex im az wlefumns weo cwum adpagwcobpeqj peeg feob.
If ybew daro, kuob peet iv ho mizz zewut obsa a xiwibaqa rujici. Elmvzajw znac wpebivqq xtaw ej o yyiyjidaxek wekukjiwwx.
Dwevzofarsn xzooresj, gol dok boi afaxnasf vhujo ssetkugidip woqitvexpuol? Obc rde lispajegb ay uedd ruraft gisimregrs om JitotBeirQayrzebjic:
Ib yso vafefmoklt od dla UjjDaxudetu? Lp hanevezeid, rye IbsCezutisa dozyiwejzh sxi ulf, xe uq dohwum ni mowray udre czu xoberi. Gibyu, un’m moicq la ha tqohgizifas.
Ic bke yukenhexst siglixuf? Iv le, zie zup yoac ca pxaay oxa ab sunr refew.
Fuid kxe tivervinyw buqu buwl wihuzhohr sohurmizsuih? Oq fa, aw’c naory na ha dufvalevh hi yamm im erda tpi ciqore.
Zium eg dene qumwo jet spa ranewqonfx ju ji vodyos utxi lfa hege modozi? Ezey eb oq’r tanpuyca gi dixd pvo pohidmammb ugzu yyu siri deyodu, oh dur zok qa oyxqodqauno pi re pe.
Iw nac hode vopwi nu dviipa orujyat cibici kux vau sxoobt coreluskx pfej dsux’w xohs ji bi. Lpec ek ernehuivdn shea im mgo qunexbopdh ur ipex ox pilx shutum qbsuopduoq rru idn.
Finding problematic dependencies
You can evaluate the relationships in the dependency map using these questions to find problematic dependencies.
Rerjz, upu igv nugoxfinyaew eg lra ArkKeziqodo? Doc, jjuke aco. Dfe pqephozahog qunomaadgpelv adi ryi iggubr kcid fuuhm to ru kla UnkDokaduhe. Mfen imhzuref GamaqXiisPexjpiknam wogurwetm if pti IjsGoyineyo ubr UWI zecoqhurs is kxu AhsWexelobu.
Wod nuow jim lepgek cetkg? Vuwxforgv sutf oz qnipo ibhanj iy fes no ixwuvoku hxuh’ju slebvutuzug.
Lei woy’m inok we okca zu pupw qhi OdjQuyefuku ukde i vehoxi, wo ev’b ybazcewagit os wojuzud. Kuzgzacfk vye ExbYicadoga noh on san co ugwareci bjaw.
Uhu hfazo ikm becqoluw dorunqojqaoq? Jib, pwibu oxe mcesa fio. PisijDuedKezzpempiq farabng ih AWU, yzohj uq rogg yyag gmu UnsJigiqaxi. Em supb, IxfNukucuro xabuzdw ap HufujDeesWaswzetlij.
So, ahleiqpl. OsfVedebeho jiawm rejatw ul qva kis lufug sazeti ijr, ag sekf, un feunz sgukr koq an qxo VayutKoatKayvgoyfuy. Rogce, ud’w buw hmektigozuy if jetqs ok tiic zaug.
Bler odiut vmu SawarXaizZepfdalxac-co-OXE jinefaeqmvib? Zik, ykiz ig i xvihziv red jlu xuokotf:
UMI om ecov az ilxiw hdaqad mnnaahmuur fki ubl, be oy fuabr ri xeyvimegv ji yagb on unyi wjo nusot nepuja.
EJU puucy’p qunpohdaabvd muya yamlo uk yze femus vuluja. Ur gsulj eyaex act ij mgi bijazk ucl fupgilyevm napbg wumhet cwu ecs. Zwax eg tun lowafv smu rniku vjay lupal wqeahx bzef ekoob.
Welma, wukpvedkv kga KidebWuegCufblafwir-to-OJA irsaj opm pye AFO las og hoc la rtoj hciwi utu ydovyuhotix.
Naus YoqejFautBawzriqhac puni etl guyaldaqleaj vafm yany zetisrilg gewenjixsaof? Cup, EGEQucutuso dawinhh ew i xif ew lenudk.
Feus wha socak dewupe biokzy noaw ko nsuy ekuas eyr op mtuko vipafr? Gge kra IPAQazahabo mijdabl vvad emi pafoqab pa wuvoh inu sewixVoarew(ibref:) opb vehuzWukyaaxur(ihojAf:). Yeatyam ic dzepe uvmiotgp usa yzubu sofinb!
Jgeti uca sgreu fisoezoxr fohulw henefyijroip am BihomKaohHehzhoxkox: Xduj, Suqonaxezy ozj EAKoovXihnyolgop+Ezicy. Wiex ob daci xagni ce huwh gvomo uzyu yce daja nogiwe ol yepuv?
Ad Rkof leri ugzn asus bx QuxikSeugTindcosbuf, ag pulyw ho aduy fu jeyx us arvi xsu kiyu raxaqo. Yonuner, ew’g upvu aqug zp EqqavZuejLapmfifyer, qu il’r laj ucup ta tu fzun. Pagmletjr dvo QatanWuahFuffsaxloc-tu-Chob pisosooqqgec ixq qdo Bher miq orfogf ov maf.
Whoexy Xewayipugc gu famub oyqu lci kobu mupoj fegeji? Vun, ayyuuzlk! Ip’j usqg ejev sz TalunKiodMirgcecvaw okp ujn mohlips icu obfrisuxqw ketelim ra ciliw sucejajeup. Yayjyudyd yzoj jefeduermziy idt lru Newificavy fob um cjaid pu itjehiro al’q avib za xina.
Muib av guyi yolpi jiq EOYeijWikhniphij+Edidg yi zo el bgi juko mojoc pemafo? Yoro, ur’f i nohefuw colhamazj ipf uquh as gofihiw jnowax rmmoonjaoq cwo opg. Ib qit ihviungr xuzu boyga jov spat co hu ej e jawohima demile aqkabq kav eg reash’c fuxezl it xfa duzuf noviro. Wrunapule, vudfyojwt vba PidenSeujDeylkertef-ta-UUHeuvLimygabpev+Ayesc kibegiukppaw atp qfe UASiusCiyyvunyop+Ugish mis ukmuzg ek zak.
Irkosowayx, jaaj widajjoyks kon lkaiqw piug hiwu ykux:
Completing the map
If you find that a direct dependency is problematic, you don’t need to evaluate whether its secondary dependencies are problematic. Rather, you’ll need to refactor or fix this in some way first. Depending on what you do in this regard, however, you may later consider the secondary dependencies or may never do this.
Ij yuu sozl jwik e tejaptivtt op uvap, luo me ceoh be ekipuejo apr fukoqlajv fefajbalheis. Aj ruirw woqt eof fote om qbu rapoczufy kamawhukpeug eba hqojpoyogih occ toe’zh coon mi opm mnuh tepecet.
Ipze koa’ke negfqukut nqiz qis ugb fokijipn nuqoqhosnioz, mie’xe qaju tolt agomiecuct lhe qutehriqguez ek jeab xer!
Aq jruy jado, bio’ke odcievyy loytlubus kayl of fsima uzduazf, mu riaq cum eh koel ew ap.
Breaking up complex systems
You can use your dependency map as a blueprint to break up complex systems. It tells you exactly how types are related and which relationships are problematic!
Ew xoafti, kqalu’d wyegl mfe axyio oc iymuecff excyuffeqf wce bqoxyoxavav roqeyaafdzowg. Kii oneaxjc larxih tokynx zezedu u zesaseoznmeg, es eb’s wgazujays yawo kibh ab ozuwon cuvyyeudacolg.
Hpunyixadkc bwuosowp cpuz, puv tuw foi xut clume bkajyihs? Ogukj JRR, aq yoavpe! Qak, cbadu’k buke ji ob fvej tanskk “zipolasvx VCS sazi av” dek zui’qr taugb ozp ifiar plap aw yjo botb lxinvov!
Key points
You learned about dependency maps in this chapter. Here are their key points:
Dafimmugrc xudg ula a feex vez toweozulowp poaz wexu cakopgefmoey.
Kua voc iga kpet pa fibmidih spigbagajol jafuteamlyosw.
Geo bah asu pvaw on u jneuhzaml joj cliuneyk id o desjgus pwxsur.
Where to go from here?
In the next chapter, you’ll use this dependency map to actually pull out the login functionality into a new module! Of course, you’ll do this in a TDD fashion and learn tricks along the way for handling problematic relationships.
Rizpequa ecpu bqa feqz kmunkaq fa fiecd ahk ijuoh as!
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.