Dependency Diagram

Habibur Rahman Ovie
4 min readJan 4, 2025

Dependency diagram is a visual representation of the relationships between components or entities in a system, usually in the form of a directed graph.

This is a tool for visualizing codes through diagrams. This can be a very effective tool to understand the dependency graph of components and modules, revealing tight coupling and even retain cycles that could potentially lead to rigidity and memory leaks.

We can start this at the very early stage of the development even before start coding.

Writing Dependency Diagram:

There are different annotations, lines and arrows to represent dependencies in your project. Here we will talk about some main ones.

1. Solid line, empty head = “inherits from” or “is a”

A solid line with an empty head denotes that a class inherits from another class.

class  MyViewController : UIViewController

2. Dashed line, empty head = “conforms to” or “implements”

A dashed line with an empty head denotes that a component conforms/implements a protocol/abstract interface.

protocol HTTPClient {}
class URLSesionHTTPClient: HTTPClient{}

Here URLSessionHTTPClient conforms to the HTTPClient protocol.

3. Solid line, filled head = “depends on” / “has a” (strong dependency)

When a type instance depends on another type instance to exist, it’s considered a stronger dependency.

class RemoteFeedLoader {
private let client : HttpClient
init(client: HttpClient) {
self.client = client
}
}

Here RemoteFeedLoader need an instance of HttpClient. Without this the code will not even compile. RemoteFeedLoader has strong dependency on HttpClient.

4. Dashed line, filled head = “depends on” (weak dependency)

class RemoteFeedLoader {
func load(client: HttpClient) {
client.doSomething()
}
}

The RemoteFeedLoader has a source code dependency to the HTTPClient. But it doesn’t require an HTTPClient to compile RemoteFeedLoader. That’s considered a weaker dependency, but still a dependency.

Example — Now let’s create a system diagram. Our requirement is, To load feed from server , if there is no internet, it will load from a cache or local source.

import Foundation
import UIKit


protocol FeedLoader{
func load()
}

class LocalFeedLoader : FeedLoader {
func load() {
// Load Feed from Local Data source
}
}

class RemoteFeedLoader : FeedLoader {
func load() {
// Load Feed from Remote Data source
}
}

class RemoteWithLocalFallbackFeedLoader : FeedLoader {

var remoteLoader : RemoteFeedLoader
var localLoader: LocalFeedLoader

init(remoteLoader: RemoteFeedLoader, localLoader: LocalFeedLoader) {
self.remoteLoader = remoteLoader
self.localLoader = localLoader
}

func load() {
if hasInternet() {
remoteLoader.load()
}else{
remoteLoader.load()
}
}


func hasInternet() -> Bool{
return false
}
}

class FeedViewController : UIViewController{

var feedLoader : FeedLoader!

convenience init(feedLoader: FeedLoader) {
self.init()
self.feedLoader = feedLoader
}

override func viewDidLoad() {
super.viewDidLoad()

feedLoader.load()
}

}

// Composition

let remoteLoader = RemoteFeedLoader()
let localFeedLoader = LocalFeedLoader()
let fallbackLoader = RemoteWithLocalFallbackFeedLoader(remoteLoader: remoteLoader, localLoader: localFeedLoader)

let feedVC = FeedViewController(feedLoader: fallbackLoader)

In the above code, we define the FeedLoader protocol and create two classes to fetch feeds: one for local feeds and another for remote feeds. Both classes implement the FeedLoader protocol.

To handle feed fetching based on network availability, we introduce the RemoteWithLocalFallbackFeedLoader class. This class also implements the FeedLoader protocol and relies on both the remote and local feed loader classes.

Next, we create the FeedViewController, which depends on the FeedLoader protocol. Importantly, FeedViewController does not rely on the concrete implementation of FeedLoader but on its abstraction. This allows us to provide a remote loader, local loader, or fallback loader, depending on the requirements.

Finally, in the composition phase, we assemble the dependencies and inject them from outside the FeedViewController.

Dependency Diagram (Source — Essential Developer)

--

--

Habibur Rahman Ovie
Habibur Rahman Ovie

No responses yet