(翻译)C#中的SOLID原则 – 依赖反转原则
发布日期:2022-03-13 05:36:18 浏览次数:15 分类:技术文章

本文共 4394 字,大约阅读时间需要 14 分钟。

The SOLID Principles in C# – Dependency Inversion

原文地址:

The last post in the SOLID by Example series deals with the Dependency Inversion Principle (DIP). It states that high-level classes should not depend on low-level classes. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.

该系列的最后一篇我们来讨论依赖反转原则(DIP)。所谓依赖反转,是指高层模块不应该依赖于低层模块,二者均应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

By dependencies we mean all lower-level modules, used by our code, that are likely to change. For instance files and the filesystem, databases and datasets, third party libraries and components, webservices, configuration, system resources, logging… and so on. One could even argue that the .Net Framework is a lower-level dependency.

通过这些依赖关系,意味着我们代码中调用的低层模块,是很有可能发生变化的。比如文件和文件系统,数据库和数据集,第三方类库和组件,web服务,配置文件,系统资源,日志等。人们甚至认为,.NET Framework也属于低层依赖的范畴。

In the traditional N-tier layering structure, where we have maybe a GUI, Business Layer and Data Access Layer, we see higher level modules instantiate and call lower-level modules. This is creating a dependency from the high-level GUI through the BLL to the lower-level DAL. These dependencies make it much harder for us to change, maintain and test the system.

在传统的N层架构中,一般会划分为用户界面层(GUI),业务逻辑层(BLL)和数据访问层(DAL)。在这种架构中,高层模块实例化并调用低层模块。这也导致高层的用户界面层(GUI)依赖于低层的业务逻辑层(BLL),而业务逻辑层又低速于底层的数据访问层(DAL)。这些强依赖使我们很难对系统进行修改,维护和测试。

In this example we have a BirthdayCalculator class which has a list of birthdays and a GetTodaysBirthdays() method to retrieve todays birthday list.

在接下来的示例中,我们创建一个BirthdayCalculator类,添加一个表示生日列表的birthdays属性以及可以检索所有生日列表的GetTodaysBirthdays()方法。

We new up the birthday list inside of the BirthdayCalculator constructor.

在BirthdayCalculator类的构造函数中,我们实例化该生日列表。

public class BirthdayCalculator{    private readonly List
_birthdays; public BirthdayCalculator() { _birthdays = new List
(); } public List
Birthdays { get { return _birthdays; } } public List
GetTodaysBirthdays() { // Update: 2012-08-07 // Made an enormous booboo on this piece of code before // Solved thanks to Dejan return _birthdays .Where(bd => bd.Date.Month == DateTime.Now.Date.Month) .Where(bd => bd.Date.Day == DateTime.Now.Date.Day) .ToList(); }}

The birthday list is what we call a hidden dependency. If we create an instance of the BirthdayCalculator we don’t know it has a dependency on the list of birthdays (a lower-level class). Another hidden dependency is the explicit call to the static property DateTime.Now to query for the current system time.

上述代码中,我们调用的birthday列表是一个潜在的依赖。在我们实例化BirthdayCalculator类时,并不知道其依赖于该birthday列表(或其它低层模块)。另外,调用 DataTime.Now 静态属性获取当前日期的做法也是另外一个隐藏的依赖。

Let’s inverse these dependencies. We do this by placing a small interface between our modules and let them depend upon these abstractions. In this case the IList of type Birthday. We new it up outside of the BirthdayCalculator, injecting it into the object via the constructor (dependency injection). The class design now looks something like this:

通过在模块之间设置一个接口,使模块依赖于抽象,我们可以对上述代码进行依赖反转的重构。在该示例中,我们在 BirthdayCalculator 类外部实例化Birthday的IList列表,在BirthdayCalculator类的构造函数中将该列表注入(依赖注入)。代码如下所示:

public class BirthdayCalculator{    private readonly IList
_birthdays; public BirthdayCalculator(IList
birthdays) { _birthdays = birthdays; } public IList
Birthdays { get { return _birthdays; } } public IList
GetBirthdays(DateTime checkDate) { return _birthdays .Where(bd => bd.Date.Day == checkDate.Day) .Where(bd => bd.Date.Month == checkDate.Month) .ToList(); }}

What we have here is an independent class with a constructor clearly stating the dependency it needs to function. The DateTime.Now is gone. The CheckDate is provided whenever the GetBirthdays method is called. We can now change and test this class much easier, because the control of the dependencies lay outside of the class.

可以看到,在BirthdayCalculator类的构造函数中就明确的表明了其功能实现所依赖的外部接口。另外,DateTime.Now 也被去掉,代之以可以传入任何时间的checkDate参数。通过将依赖关系移到外部进行注入,使该类更容易进行修改,也更容易进行测试。

转载于:https://www.cnblogs.com/mcmurphy/archive/2012/11/13/3357578.html

转载地址:https://blog.csdn.net/weixin_30323961/article/details/98280842 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:《bootstrap》实战---小问题,大Bug
下一篇:html个人网页

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月06日 19时45分42秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章