DEV Community

Cover image for Dependency Diagram: Understanding and Visualizing Relationships
Gustavo Guedes
Gustavo Guedes

Posted on

Dependency Diagram: Understanding and Visualizing Relationships

This approach is very useful for clarifying the dependencies of implementations we are working on or designing. It helps in understanding if each change is being made in the best possible way.

1. Arrow with Linear Body and Empty Head

"Inherits from" / "Is a"

full-body-empty-head

Used to indicate that something inherits from or is something else. For example:

is-a-reference

In this case, the MyViewController class is a UIViewController.

2. Arrow with Dotted Body and Empty Head

"Conforms to" / "Implements"

slipted-body-empty-head

Used when something conforms to or implements a certain contract.

implements-reference

Here, the URLSessionHTTPClient implements the HTTPClient.

3. Arrow with Solid Body and Filled Head

"Depends on" / "Has a" / Strong Reference

full-body-full-head

Used when talking about direct dependencies between different concepts or things.

class RemoteFeedLoader {
  private let client: HTTPClient

  init(client: HTTPClient) {
    self.client = client
  }
Enter fullscreen mode Exit fullscreen mode

In the example above, the RemoteFeedLoader class directly depends on (has a strong reference to) the HTTPClient. Whether it's an interface, a direct implementation, or if it needs something external to function, or even if this dependency is necessary to create the resource, we're talking about a strong dependency.

Therefore, this dependency can be represented as:

strong-dependecy

4. Arrow with Dotted Body and Filled Head

"Depends on" / Weak Reference

split-body-full-head

For this, the dependency exists but is not mandatory for creating the resource.

If we change the approach of RemoteFeedLoader to:

class RemoteFeedLoader {
  func load(with client: HTTPClient) {
    client.doSomething()
  }
}
Enter fullscreen mode Exit fullscreen mode

Notice that the dependency exists, but it's not necessary to create a RemoteFeedLoader resource. However, when the resource is called, it will be necessary to continue the process.

With this approach, we gain more flexibility in creating our instances, but in return, whoever uses the RemoteFeedLoader will need to know about the HTTPClient, while in the first case, we don't have this issue.

So we can represent it as follows:

week-reference

5. Colors for Each Context

This approach clearly shows when something being used comes from inside or outside the context. This makes it easy to understand if something is breaking the project's architectural pattern.

colors-reference

Conclusion

In conclusion, dependency diagrams are powerful tools for visualizing and understanding relationships between different components in software architecture. By using various arrow styles and colors, we can clearly represent inheritance, implementation, strong and weak dependencies, and contextual relationships. This visual approach not only helps in designing robust systems, but also in identifying potential architectural issues, making it an invaluable asset for developers and architects alike.

Thanks everyone! See y'all

Top comments (0)