Hide chapters

iOS Test-Driven Development by Tutorials

First Edition · iOS 13 · Swift 5.1 · Xcode 11

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

12. Dependency Maps
Written by Joshua Greene & Michael Katz

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

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.

Finding direct dependencies

The next step is to identify the type’s direct dependencies.

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.

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.

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).

Finding problematic dependencies

You can evaluate the relationships in the dependency map using these questions to find problematic dependencies.

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.

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!

Key points

You learned about dependency maps in this chapter. Here are their key points:

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.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

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 Personal Plan.

Unlock now