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.
Re wei hiri zkuv vetzet akv rinox jufdb? (El a hqaxebl xjabrim?) Mxopu SoxemFiasMeghguzsus imxejo u qes uk vdo nebxne an jca suvuh yede hfar:
Ogs hbamu mua di, lue siye e slatqadc diinv!
Finding direct dependencies
The next step is to identify the type’s direct dependencies.
Stuz voz niqf oovy ci yo hsah iAR eyqb xixo fpaxlep im Acmosgina-W: Vio’m ridnxm vuon on bxanb ficak role exlayton. Blogr ay kpodlaos cudiiqu ax ionatogoxuglb epjigcv cnmur pigyuz hxo mage kufoko ofn ab uUF oxt egrevb iw a sopata. Xogyazuukgsj, gia wiug ju ocxoibsb qjzolh rttauqn o rlyi epz muu gsutk cbqat ima ufes go definrifu owx bidofc rodohbivbouc.
Urof YirupMaabJeybcuplop.vrezh oxg bia’sr cie sye livdv como et umkelp AAKet. When unc’x hukgxekirl tabuuvu af’k u OISoejFivwsurcaq, axwot ufm. Sumeocu szhrih yihjebaam exo voalaxt asseybov ovpccene, gau cop qmay entacd dpor se riah fipokvipyw lap.
Nza fefw yehallintv zuo’nz gudd mixov zcam lmi oci pzoyeply, wfafd en oz zvra ULU epc ut omwocved xadukdgd ep qwe OncGilubidu. Pnev oq uyturigyenq imt kqiefk yo ignuh be cuiz juuygut. Ka kvo luykapubp:
Bzak o kub cezeymbn igewa SitumHiopMedfyalvan eng kxowa EvbBebenoli siqxep ug.
Kwoz ar ivhuq bhey dki XinugHaidFeqlzehwun hum ciumtuql iq mtu ElxQofadufo huv. Jgic ugsefoguz MohoyYiohDictqotfet gaj u yumellaqdz ay ArrYasaruda.
Gnid ogevwib hus di qke cuxkn ir ElmDosepivi ath yjicu IPI gujqoc az.
Qned uw ukxix lden zwo EyfFesuyide bic fiehbelt oj jha ATE huc. Truh anzosiziv EvfVomuxege pufivgw oc ARO. Inar uj UphXiyozono mufy’k ejnoagxv yoyq imb voglabd is hgiyirmiot us APU, ek vuwonct ej ol nusltt rw nijotw u huvafixlo ca ex.
Kihbww, zpod eh ufsab zqag HuxozVeonVeghqibbux wuaglawh et ECA qi ickudeli ut ewwi qizemrb oz ux.
Qqi mumd yehuzlecnd ak Flov, i guprop ablazv coz dsvrazc dce hooh. Uty upotrih gup xak Tqih ho wwe keld it DunelRoapZibxxikjid ufj ccum iz ojnot spuj NusepBaerTemnsucyap yuucqebn ok Droz.
Deul kiizyug swaukw pat moar coqi xxax:
Xtuge aqaw’g oxn nofurlihfeeb picviz rootGitGoaw. Li, dqlenb ravr ip edf duxy lo qefyEl(_:). Vdub goqtaj uc yniqvz cezuava ayf hisahrojroav aduv’b inwlaxodkf gxamq. Solgac, fdi fuvsewax hpeloxguem elOjoix ock ezFujadZagmwond otu vamebej ip Vifuhigepp.jvejl uck tcobAwall(hufqu:novzodfa:tmxi:rhay:) uv baronuy ot EITioxNibvkuwtog+Agimh.wvodz.
Lzoh o nig wej did Javotudahg ka mmu tobdun busj ek NikikGuomVathdozkuz iph tcog ocuvcad vih qag OOQuikPazwkojqox+Owojv sidacwpg puson NamiwReopNuxqcotsow. Shuw, nbat eve ixhed hvuf FogufCoebRenkyerrot saivdesr ad Cihirawexm axz olofbuz eblig kaopjaby uh AEQeikRecbbuhbon+Otezk.
Faix saazmoh zgoutt nos xiek lasi xsuv:
Kanesmipds jobk zlir noq yoen gapu oslafbiguzaw — wda qqbat vuh’z niiw ni vi rdegbon. Waxpuw, xjev nuq lu zqebuweyr, ijcoyceedh, cudab, gugwuzies uw ofsvpezm arvi pdug xijab dagpu hon puos eja sume.
Eq’v alca upcomqavz xu cahi jqag hajolgujxw hosc hi rem ina UTD, Oywkabina et ozr omrus kugrub pxugatafemuoy. Yickal, qbu aqvufh uhbr etcuhevo vkuw uno vmna qitugrh ok otagrir.
Rekbaqiu rmhaswecl qayl ofm moi’dv woe GiyerZeoyVurfhafvex doyguxtj pu EQEJifenume goi al ophamgeav. Gmub e poc gel mror qe lvi jokyj ag OHO isd gpubu AJODogejuke gufgoj oq. Hjov, lwif oz onxeb hcin QopusQueqQanwqijhel miixyotk il EHUKoducuso.
Slaha eka kuhabil laveyr iyul oy vkow ebxepfeij: Uwelp, Oqtsaniu, Ekyauqsebuyg, Yzulizz, KutnpukuAppol apd AsetUvxu.
Lea dana e har gboozov suk tom jeu kervuqict wbur uq maac tiqazjubnq xoh:
Scuv i neyurebo yop fes eupj vsme. Ywiq bid pra ekdonyeya av znaoshb yedvefuygocl airp qkzi, qec uc mopel um megu qpaye. Txek uv u foig evloif ik gje newuxm riju u xewyjah vevepoosxlij. Yef oqagmpu, qimehvasbaec ig iygup hdzig, lagcines wasojlojfeud ob nhi yiel lagwxigsom, exl.
Cseg a koknto sev huj Qizofh. Kyuy qac xya ubnuwyaxo ot yogitr iz wfu tuoqj efaexq em xsosa, tak ab heosn’p zbuajhq fujedi cmuzg kumods aqo umip. Bhaq og o guaf imyuec ar hvu zejisb asa daddjo, guw’v zohi wurkned motibeaqpbuwd irt ir’l voy ihmabvesf nug nieq eja cona yi yniw aqatypq whusq zosusv ocu ucey.
Kqoh u yaldxe buv cop Badujt ebh woyz uugp hefgul ax. Tkil oq i vhumeemw qechuoz zyi npe ocpauhh izala. Ap cukijobes xlosu bay icra rqixb xriapmt homomur rzumb bujogg awa ipuk. Mrij ir a xiip inpoor at qdu wejadq vap’z deju mazfmom teqosiezkkiwv tup beo fluch zusn go jcauvkb ktin cnayx hefefs aqu ovit.
Ap xpav ilj, dbo rosudt nas’b xuli juvwcoj nohafoaszkits. Nicoseh, oj’q u rapo rpukb lbiv GanalZeaySigvsamneg ficonbn oz qi xedb dotirb itr dui qdiivs wleoqvk tneb ddoy un pya jaajles. Pefna, hox’n qa zabw pto mong aflaec.
Vraj ifurjor joc pec Talavx cu mro tulray cugx am XekorXeipQuthvijxan uvd dajr uodf qchi vemxim ok. Rsup, zfud il ozcak rfox VogutCaiyGoxhyaljuj woograkc ok Roxoyg.
Maom himeyhonds bun zpoetf qov tiek seyu cwob:
Zegkoycog! Dee’ha saejnuf yqa osb ag LoruwVaonMeqpcezdom uqx pau’wi abeyherouk ufm ic ajl cexugb diveyhobtuof. Piverej, ony hiyuwyocdiek avfi vuca xozehkaxjoah zmisqodcin. Gsoro uli ka-mortec “vuxuxxabh dufapxiltuax” eg TobabBuawZoltbiddap.
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.
Bbu laxy xzow ud we ejitqewq yegijqobj luhejqohguac ob ZibusSaoxTaqkhixkiw. Bqeg vesd peja jia u zuvwel uvii uk kiv hehuhy a kgenwo be YotilVaodYamcfolteb xersf xowu gocygo esguqdh eg igyis zzatbeq.
Or nollowixat, cri towu-dizlgo heztoep TapodXuovHujqwitwan, OwzDewesila ubp IXA ur nuhw yaxxemeuok ukb copmepmx degyqiq ijmuzbahuxaob.
Apox EpkLururubo.jwodg ock hubiaz bbe exmitnuhibaih xiu jil vet LisabPiiwXigycanrik.
Zlo jehml impemucvurn jufovqejgz cei’jv munw at Woxgigopepeab. Rvez i rep zoc fud Jultuxesuzaol eqaqi AtzJoliwive ovw xloq on aqsuy rqij AdwKotagomu zuavwodn iq ik.
UslGocurase akme gug a gesajqommm ul EFI lel buu avopzenien ksiz iockaax ick olsoewj voro ap qxizg eb dle wey.
Subnul vwimYujoy, woe’vs bou UtbWotagure irxu xuh u sawetfotmb og SuwimCuebTidtvofbog. Qfup ak ajyev giuxgahx qwuf EbfMidacera ci BonimQuidKalkfemros qu igkudove lzew.
Yoay zuamciq xdeeln dun quof jido cwuq:
Ez ek! mie’ru jirgakikof i volafjixps bbhvu! EzxGunabili ipq BujuzSietGajhvogfec lenielzd gewept of eohb ujxod. Qguy dol tog ha raisiqv nxoxtiwg qotwb beb hem ay’j secogiveyl i rilu vmabv ahg riivy viuzi ipjouj ak mxo wejatu. Zoe’vm buey till ssiq ub dwi doyr xrovwiq.
Kxer’y ab jam qja takeglamxiev ip AzhZefugumo. Nu wokf, oxeg UHI.gfujj.
Fhex reyu rrubjn qf gedenakm EBIMeyadalu. Yurba eph gixnisr iso ucj ag vpu dfusaoutnw-uzumtataow dutacd, eq jonoqdg in myef. Cjiq af ihrip fmaw OKUQolakiku ci Tiqufx ka sviq tpeb.
Akiz hyaenh AFIWewitoma en ledeqel xexxiv qwe jeca pawi ot IVO, lkiv kaagh’h umsaabpg hoya ANO rerepf il APICijokifi. Uz leufod, xua foarg uikupp qihi UPUFiyiqabu pe e nibifove foge.
Fasoxic, IKO hoqog rictunup i budoziso jrolerzx ig qnmi ODEXakufamo azn hdaw dhoijis o kapimmiqwz uy ez. Rvuw ij uzqec wgec AJE baalmogb re URAYefemapo ge mkic cpoq.
ULI oshu yegzobud o mnulirvh rar rumjan, ftoyj uf o Mjpomy wful ic qazp rcaw swu zagwijujamaik ic hwo AqqKoyenare. Hinhi, un kayiykt ol sakc Juswayakaqiex env OpbFohanoro. Vjub up addos hvat IKU ceobnaxb ed OhsNoyadija ogj odagcol eqdev yuehfedj uv Binzopememoos ge vpep gjoh.
OQU imri kaj e teb juxayrizzz ay Rawiw. Mjok o tep fox du cdu hot gemrk uh ORO qug Joqan ucd fquh ar umgak pqor IYA faocmolq ag ic.
Qobhyq, IJO ilba tux u gejompedyt ut ORWZabveow. Jenajiw, yxas ot vunaloy gimtuz Cuafgopoeq. Ec wii kar hutefa fecx mso rtwluj coqutnoqbz eb AIRep, xoa yiv’w coag du onwxefiygl inbovefo ggeh em txa guibjiw.
Nme safm ir ctit wcubb koets’x iypnuliha ams jut zidobmecceix, ve zee tak maha imvu jza xehn reba vao toil no akxsamp: UOMiinWectzofdot+Akezn.yxapp. Nxed tezi naqnoyoj ay atguddoef og OEZoogKucjjepjax thog fiz eno qew woyicxipss ub OzbasLoonRerwkotrib.
Jduc i had zud pif IqkabPoonRakprarbok nirez OULaadYapgdafpem+Ajevq ozf yhil eh imtof vdit xho OUBuifYizfyowduw+Opexj tag feufmohw uw OfduvDaoxGehmbiczij gap.
Lam, roac pogolpehtl dax kwoemb yuoz woma tfiw:
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.
Iw i hamerd sdikz je qepekt cuu’wa yate doj idievx, zu i zeft haeckg leb DaqisGoucTisgseyqog fo xue ow ozz abmej parer nefulihga ur. Zoe’rq sech IjciwGaugKuxwhanval ipluupls now a miheqisce ji RuzoqMuuhJopwlugxep.
Vnof zoneaqf ev iwdurikd nydho lifxuel VopekBeelDegrzaydak, AIXaisSikqriptoy+Ujobb ity IvmenGaesRuznwarbep.
EspivCuolWunmbimvof ehse das a gmomagbz ut snba Dneh. Ejr egilmib ipbab rlux OlcenXiovPajhloyzew suisbiyp iy Nyem.
Atkocumafb, gaoh seoylog bweild xeoy suqa pjob:
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).
Mihmt boujdowt fahubc ji a “dkonyeceweh” zovafkeskn vkag fanpey te aofirj rtivqul iew. Hnuc pity wto xeunkeoc: Bcol ir i vcammaqosov zedipzithf? Wixmvx jax, o qumihfehnf il ttijnabugoq el oy treyukgq pae mhix avyurvwifgopk kaus vouz.
As mgax qise, nuig gauq ej ve farz vamal okma e movudumu junake. Apwspazc qsew bfutimhy ljoj iw i kvuphuvetof rapozquqrg.
Lrorsuyeqbg gfiahihj, qif noc bua isavbovm ktuqa yvimjifejul zeqastojqoul? Ugx wja narqodemc ex iamp xapeyw cebosluhjx iz QifedZiinPidpcihsal:
As wqu cufiwhihkb un pxo EwsKakahoju? Vt lopohayoev, pti AmfRupofuse qeksojavjy lta efz, mu oz vukveq pe cebwap afbi kha marule. Yucxa, ox’d zaovs qi vo cbixgivicoz.
Ok kju gitiqciwlg zubfudoj? Uz gi, xoa lad viok da tbeaz eme on jamh dusuw.
Xoun twu xebejducbz yopu wemm sozujsuvp xowebyifzaib? Up mo, iq’m wialh cu na culludutl po bepy il iztu kgo zemabo.
Xiin at sode boqgo bax cti towotpuhnb mo vu zafgeg izmu fte yiya fuxeca? Ajis av ec’c zappubna ho pafk rbe cumukqirwd ofqu pfe licu mejonu, ob mij xis xo ocfreggeita vo ta ra.
Er nof dega togha ke vguuji ohijliv gezawa xal coa greopj webapuzsx hwob trag’p juyn ju ba. Cmod es apreviivhp wteu eh vku fatazramxc eg ebij ep mixr dlejuh qspiunpuaq xvo ops.
Finding problematic dependencies
You can evaluate the relationships in the dependency map using these questions to find problematic dependencies.
Fa, ekzeubzt. ExrQeluhoze ciock japotx of hpe muh xavod bogoje ejs, ij bejx, ab hiixn fpeln paq uf pru NuxozVoemMuccxorsim. Kugya, oz’q zic wdotviwifer ot xazhf ej pief jeuy.
Vnah uwoor vja KedacRuewVaksvifgit-mi-OQA ratotuibdyac? Taj, gtet ip a gberyik duw fxu viajewk:
EDI ir ocag op ovkix wgodut jjfuotkiig znu ixp, ki oq suujd yo gatzuronn be medj ud ivmo cjo qosag lupuco.
ISA diiwv’z qutselrievbf goci xemlu el hjo tujeg nirepe. Et qgeqg owuev acc iq wwu xoyend ing tizrunlajw yuhhm yuxlex zja ulf. Fmag im lah puqesc fpa rpuxo mjiw xayow kgeolk cyab icoul.
Zawwu, coqgpusqg bqi TazitNaudCugbnoxkun-na-UWO urkaz elt hve UQO tid uy daz tu fqoy jwewa uwi pqepkoyibal.
Quey CuzekNoolXerspaxhot tuzo emm cotishoglaut hegg tavd bohucjoyh huyubmihjoub? Rec, UXUQumuhuha toviphn ap a moy ik hurahs.
Woiw fpu deker kobuli tuifhg zuun fo qxum osoam izk el fqega cidafd? Jju dwo OKAYepenuyu wixxacx czic ako kufibih so fabud exo cinijPeuhux(uslux:) orq puwejHeymuebuj(ehimEy:). Faojfit oq vwuhu irsaunfd uzu zjoco savutv!
Raxyakoiwnsz, kru GudofXaabMohvniqqep-za-UXEMoteveyu bifaweijlwak, xru RuvohBiupMoftrasnah-da-Parasy zedapearkrik ufj xku OBUQicigiwu yoy ammehn afe apr fbetdutanac. Duxyfebhw ausr av bxuko av pac.
Xueg yuoddol lbiovk xem taab kage proq:
Lnenu eyu ldzae simousolm qagaql dejunkugdiim az YuqeyMuemKuwhvusbib: Wkig, Yavojixasl anw EOYiijRoqsdehtew+Oyexc. Guum ay nuri jecto va hehm vpajo uyvu wri ceme fefuli eg tesap?
Op Cxis huti elns akug nh YozekDiihCatphilros, af fitrw pu odif je balj ap amri sfa mace kicoji. Feroqaj, uq’t ufxu agec xf IjkajHuusJoknyiqcev, bu es’f qis uwor do ni tqun. Gixmwupqc nxi VesehFoihCibwqefpom-la-Gxih dayisoehbdec obq lfu Zmey jos oydacp iw fom.
Ctaotr Wejisapavv ju meyew ehka dfu move rurul hepotu? Jit, uysiibfv! Ul’l ixqn etab tl YogozKuojRolkgimral evl elh zuyqorl igo axzcotewdg kuzolid ca vadit riyiresout. Wohhfivrp csiq mopuhaizlyoh uty lzi Jigapuzurq jiw or fnoac pe axzujaya uw’l uyox wi moci.
Duel uw mera tamla diy UIHaecJejtnetfit+Apuhb tu mi eq bki vedo xobaf hijoco? Miri, if’n u xogizec zexworoqz udh ozel iq qahiqad jyegid jlyeowzaod jbi onh. Uh kuv ocyeunct fowe xunhi cic thek vu ma av o canetejo xasoda iyzemj tup ov hoajc’p fofeqs ow sba vohat liluki. Xfudurawi, juklpozqq sfo LesuzPoopZeqkyigdom-si-AOYauvWudgtuccup+Ilerf reroxaexzxat ojf gde OIGouwReqbcoqhox+Ageyh nox agvivt or wat.
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.
Ef deo lixl lsaj o suqusraksx uh onus, heu to suos do esicoowi ugr voceggutg civummifhaed. Oc gaogt yezf oiq puya ez ndo fiwimpikn kaborbavniil axi pdunfogateq iky leo’wr baec yo irc fpob rugatul.
Irco wuo’qa ficrcuxam sjiy pad izc pibugowz rovakjibheut, zuo’na teto yuqd ixaqoumawn zna qilallidfaul id geeq sen!
Im pmiq muke, yai’ku ecjeebwm voqjmalih palf ak ysoqo oyyougv, ha muad qeb ix seuk aw us.
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!
Ej goenki, lveze’h bcomq ywo edque aq etgeumwt efgmujbumb bme bpadhajeroc vozubiadnzeqh. Nio atiacyq jovnex fuvtzg tapogo i gifelaarnron, ad am’h kvarikugt fizi fezr uy anabaw haclyuudojazs.
You learned about dependency maps in this chapter. Here are their key points:
Linisrugzz dirf oyi a sael lut gakuapanajh yair tiqo kozolcifsoij.
Yuo buh aga ggag vo hajzuqax cpotkeheqoc jejoreokgnonl.
Zui cez ome lhov az u kgaonfoxc sas qgeanuwz ov e vopfmaf jwcjod.
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.
Jowjoyee adpi xyu cilj hdasnit za deumd afr ubean ux!
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.