@@ -298,7 +298,7 @@ def test_grouper_from_local():
298
298
299
299
为了实现依赖倒置,我们在上面定义了抽象类:` HNWebPage ` 。那是不是只有定义了抽象类才能实现依赖倒置?只有用了抽象类才算是依赖倒置呢?
300
300
301
- ** 答案是否定的。** 如果你愿意,你可以把代码里的抽象类 ` HNWebPage ` 以及所有的相关引用都删掉,你会发现没有它们代码仍然可以正常运行。
301
+ ** 答案是否定的。** 如果你愿意,你可以把代码里的抽象类 ` HNWebPage ` 以及所有的相关引用都删掉,你会发现没有它们代码仍然可以正常运行。
302
302
303
303
这是因为 Python 是一门“鸭子类型”语言。这意味着只要 ` RemoteHNWebPage ` 和 ` LocalHNWebPage ` 类型保持着统一的接口协议* (提供 .get_text() 公开方法)* ,并且它们的 ** 协议符合我们定义的抽象** 。那么那个中间层就存在,依赖倒置就是成立的。至于这份 ** 协议** 是通过抽象类还是普通父类(甚至可以是普通函数)定义的,就没那么重要了。
304
304
@@ -316,7 +316,7 @@ def test_grouper_from_local():
316
316
- 比如代码里的字符串字面量也是具体实现,我是不是得定义一个 * "StringLike"* 类型把它抽象进去?
317
317
- ... ...
318
318
319
- 事实上,抽象的好处显而易见:** 它解耦了高层模块和低层模块间的依赖关系,让代码变得更灵活。** 但抽象同时也带来了额外的编码与理解成本。所以,了解何时 ** 不** 抽象与何时抽象同样重要。** 只有对代码中那些现在或未来会发生变化的东西进行抽象,才能获得最大的收益。**
319
+ 事实上,抽象的好处显而易见:** 它解耦了高层模块和低层模块间的依赖关系,让代码变得更灵活。** 但抽象同时也带来了额外的编码与理解成本。所以,了解何时 ** 不** 抽象与何时抽象同样重要。** 只有对代码中那些现在或未来会发生变化的东西进行抽象,才能获得最大的收益。**
320
320
321
321
## I:接口隔离原则
322
322
@@ -334,7 +334,7 @@ I 原则认为:**“客户(client)应该不依赖于它不使用的方法
334
334
- ` 接口(其实是抽象类) ` :HNWebPage
335
335
- ` 依赖关系 ` :调用接口方法:` get_text() ` 获取页面文本
336
336
337
- 在 I 原则看来,** 一个接口所提供的方法,应该就是使用方所需要的方法,不多不少刚刚好。** 所以,在上个例子里,我们设计的接口 ` HNWebPage ` 是符合接口隔离原则的。因为它没有向使用方提供任何后者不需要的方法 。
337
+ 在 I 原则看来,** 一个接口所提供的方法,应该就是使用方所需要的方法,不多不少刚刚好。** 所以,在上个例子里,我们设计的接口 ` HNWebPage ` 是符合接口隔离原则的。因为它没有向使用方提供任何后者不需要的方法 。
338
338
339
339
> 你需要 get_text()!我提供 get_text()!刚刚好!
340
340
@@ -352,7 +352,7 @@ class HNWebPage(metaclass=ABCMeta):
352
352
""" 获取页面文本内容"""
353
353
```
354
354
355
- 现在,假设我要开发一个和 HN 页面有关的新功能** : 我想在不同时间点对 HN 首页内容进行归档,观察热点新闻在不同时间点发生的变化。** 所以除了页面文本内容外,我还需要拿到页面的大小、生成时间这些额外信息,然后将它们都保存到数据库中。
355
+ 现在,假设我要开发一个和 HN 页面有关的新功能: ** 我想在不同时间点对 HN 首页内容进行归档,观察热点新闻在不同时间点发生的变化。** 所以除了页面文本内容外,我还需要拿到页面的大小、生成时间这些额外信息,然后将它们都保存到数据库中。
356
356
357
357
为了做到这一点,现在的 ` HNWebPage ` 类需要被扩展一下:
358
358
@@ -515,15 +515,15 @@ def is_new_visitor(cookies: Dict) -> bool:
515
515
516
516
在这篇文章里,我向你介绍了 SOLID 原则的最后两位成员:** “依赖倒置原则”** 与 ** “接口隔离原则”** 。
517
517
518
- 这两条原则之间有一个共同点,那就是它们都和** “抽象”** 有着紧密的联系。前者告诉我们要面向抽象而非实现编程,后者则教导我们在设计抽象时应该做到精准。
518
+ 这两条原则之间有一个共同点,那就是它们都和 ** “抽象”** 有着紧密的联系。前者告诉我们要面向抽象而非实现编程,后者则教导我们在设计抽象时应该做到精准。
519
519
520
520
最后再总结一下:
521
521
522
- - ** “D:依赖倒置原则”** 认为高层模块和低层模块都应该依赖于抽象
522
+ - ** “D:依赖倒置原则”** 认为高层模块和低层模块都应该依赖于抽象
523
523
- 依赖抽象,意味着我们可以完全修改低层实现,而不影响高层代码
524
524
- 在 Python 中你可以使用 abc 模块来定义抽象类
525
525
- 除 abc 外,你也可以使用其他技术来完成依赖倒置
526
- - ** “I:接口隔离原则”** 认为客户不应该依赖任何它不使用的方法
526
+ - ** “I:接口隔离原则”** 认为客户不应该依赖任何它不使用的方法
527
527
- 设计接口就是设计抽象
528
528
- 违反接口隔离原则也可能会导致违反单一职责与里式替换原则
529
529
- 写更小的类、写更小的接口在大多数情况下是个好主意
0 commit comments