Architectural principles

Architectural principles

Dependency inversion

The direction of dependency within the application should be in the direction of abstraction, not implementation details. Most applications are written such that compile-time dependency flows in the direction of runtime execution, producing a direct dependency graph.

That is, if class A calls a method of class B and class B calls a method of class C,

then at compile time class A will depend on class B, and class B will depend on class C, as shown in Figure 4-1.

Figure 4-1. Direct dependency graph.

 

Applying the dependency inversion principle allows A to call methods on an abstraction that B implements, making it possible for A to call B at run time, but for B to depend on an interface controlled by A at compile time (thus, inverting the typical compile-time dependency). At run time, the flow of program execution remains unchanged, but the introduction of interfaces means that different implementations of these interfaces can easily be plugged in.

Figure 4-2. Inverted dependency graph.

Dependency inversion is a key part of building loosely coupled applications, since implementation details can be written to depend on and implement higher-level abstractions, rather than the other way around. The resulting applications are more testable, modular, and maintainable as a result. The practice of dependency injection is made possible by following the dependency inversion principle.

 

Explicit dependencies

Methods and classes should explicitly require any collaborating objects they need in order to function correctly. I call this the Explicit Dependencies Principle. Class constructors provide an opportunity for classes to identify the things they need in order to be in a valid state and to function properly. If you define classes that can be constructed and called, but that will only function properly if certain global or infrastructure components are in place, these classes are being dishonest with their clients. The constructor contract is telling the client that it only needs the things specified (possibly nothing if the class is just using a parameterless constructor), but then at runtime it turns out the object really did need something else.

By following the explicit dependencies principle, your classes and methods are being honest with their clients about what they need in order to function. Following the principle makes your code more self-documenting and your coding contracts more user-friendly, since users will come to trust that as long as they provide what's required in the form of method or constructor parameters, the objects they're working with will behave correctly at run time.

 

作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2021-11-16 三角函数和反三角函数
2021-11-16 What is the difference between Html.Hidden and Html.HiddenFor
2021-11-16 What's the difference between Html.Label, Html.LabelFor and Html.LabelForModel
2021-11-16 TortoiseGit Manual Rebase
2020-11-16 TLS Handshake Protocol RFC 5246 (TLS 1.2)
2017-11-16 Transformation in kentico
2017-11-16 Checkmarx VisualStudio plugin installation process.
点击右上角即可分享
微信分享提示