Visualizing the dependency graph
There are different types of dependency you can represent in a dependency diagram using different annotations, lines, and arrows.
Here are the main ones:
A solid line with an empty head denotes that a class inherits from another class.
For example:
class MyViewController: UIViewController { ... }The MyViewController class inherits from the UIViewController class, or the MyViewController "is a" subtype of UIViewController.

A dashed line with an empty head denotes that a component conforms/implements a protocol/abstract interface.
For example:
protocol HTTPClient { ... }
class URLSessionHTTPClient: HTTPClient { ... }The URLSessionHTTPClient conforms to the HTTPClient protocol.
A solid line with a filled head denotes a strong dependency.
When a type instance depends on another type instance to exist, it's considered a stronger dependency, such as Association, Aggregation, and Composition.
For example:
class RemoteFeedLoader {
private let client: HTTPClient
init(client: HTTPClient) {
self.client = client
}
}The RemoteFeedLoader has an HTTPClient.
You cannot instantiate a RemoteFeedLoader without an HTTPClient instance. The code wouldn't even compile. So that's a strong dependency.
The RemoteFeedLoader depends on an HTTPClient to exist.
A dashed line with a filled head denotes a weak dependency.
It's important to note that a type can depend on and use another but still work without one.
For example:
class RemoteFeedLoader {
func load(with client: HTTPClient) {
client.doSomething()
}
}The RemoteFeedLoader has a source code dependency to the HTTPClient because it references and uses it. But it doesn't require an HTTPClient instance to exist.
You can create a RemoteFeedLoader without an HTTPClient.
That's considered a weaker dependency, but still a dependency!
The RemoteFeedLoader uses an HTTPClient dependency in the load method. But it doesn't have one. It must be provided as a parameter.






