文章目录
1. Liskov Substitution Principle (LSP)
本文讨论的「里氏替换原则」是 Barbara Liskov 最早提出的「替换原则」的版本:
If for each object o 1 o_1 o1 of type S S S there is an object o 2 o_2 o2 of type T T T such that for all programs P P P defined in terms of T T T, the behavior of P P P is unchanged when o 1 o_1 o1 is substituted for o 2 o_2 o2, then S S S is a subtype of T T T.
关于 LSP 的这种表述,很多人都觉得这段描述有些晦涩难懂,其中,包括不少写了设计模式书籍的写作者。
当然,很可能他们是谦虚,为了说这段难懂,然后引出一个更简单的描述:
Objects of subtypes should behave like those of supertypes if used via supertype methods
或者
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. 。
前面那句,源自 Barbara Liskov,后面这句,源自 Robert Martin (Bob 大叔)。
其实,利用我们学过的英语,足以看懂那段看似难懂的描述。
先解决两个点:
(1) in terms of : all programs
P
P
P defined in terms of
T
T
T ,是指 用 T 编写了程序 P。
(2)is substituted for: when o 1 o_1 o1 is substituted for o 2 o_2 o2,到底是谁替换谁? 是用 o 1 o_1 o1 替换掉 o 2 o_2 o2。
搞清楚这两点,再来看:
If for each object
o
1
o_1
o1 of type
S
S
S there is an object
o
2
o_2
o2 of type
T
T
T such that for all programs
P
P
P defined in terms of
T
T
T, the behavior of
P
P
P is unchanged when
o
1
o_1
o1 is substituted for
o
2
o_2
o2, then
S
S
S is a subtype of
T
T
T.
已知: 用
T
T
T 写的程序
P
P
P;
S
S
S 的对象
o
1
o_1
o1 ;
T
T
T 的对象
o
2
o_2
o2;
动作: 用
o
1
o_1
o1 替换掉
o
2
o_2
o2 (用
S
S
S 的对象替换
T
T
T 的对象)
期望:
P
P
P 的行为不变 (意味着有可能达不到期望)
结论:
S
S
S 是
T
T
T 的子类
隐含的结论是,如果 P P P 的行为改变了,那么 S S S 可能不是 T T T 的子类 , 或者说, S S S 类作为 T T T 的子类,实现的并不好。
反过来说,当
S
S
S 是
T
T
T 的子类时(通常我们通过 继承 来保证的),用
S
S
S 的对象替换
T
T
T 的对象,
P
P
P 的行为应该保持不变。
这里说「应该」,是因为并不是每一次这样的替换,
P
P
P 的行为都不变。如果
P
P
P 的行为变了,叫做「违背 里氏替换原则」,这是需要避免的。
关于「什么是行为不变」,将会另写一篇博文来介绍。
关于 LSP 的表述,可以参考: 【LSP简史】里氏替换原则的 7 种表述方式
2. A is substituted for/by/with B
2.1 A is substituted for B,是用 A 替换 B
或者说,把 B 替换为 A
所以,when o 1 o_1 o1 is substituted for o 2 o_2 o2 的意思是,用 o 1 o_1 o1 替换 o 2 o_2 o2,或者 把 o 2 o_2 o2 替换成 o 1 o_1 o1, o 1 o_1 o1 替换掉 o 2 o_2 o2, 把 o 2 o_2 o2 替换为 o 1 o_1 o1 。
不能说成, o 1 o_1 o1 替换为 o 2 o_2 o2,把 o 1 o_1 o1 替换成 o 2 o_2 o2。
2.2 对比:is substituted for 和 is substituted by/with
A is substituted for B,是用 A 替换 B。 前者替换后者。
substitute A for B ,A 替换 B, 前者替换后者。
A is substituted by B,是 A 被替换为 B,即,用 B 替换 A。 后者替换前者。
A is substituted with B 与 A is substituted by B 的意思一样。后者替换前者。
substitute A with/by B, B 替换 A。后者替换前者。
小结:
substitute + for:用 前者 替换 后者,实际使用的是 前者。
substitute + with/by 用 后者 替换 前者,实际使用的是 后者。
与 substitute 的主动、被动语态无关。
3. 百度翻译 vs. 必应翻译,谁翻译的对?
3.1 百度翻译
翻译的结果: 如果对于类型为 S S S 的每个对象 o 1 o_1 o1,都有一个类型为 T T T 的对象 o 2 o_2 o2,那么对于根据 T T T 定义的所有程序 P P P,当 o 1 o_1 o1 替换 o 2 o_2 o2 时, P P P 的行为保持不变,那么 S S S 是 T T T 的子类型。
3.2 必应翻译
翻译的结果: 如果对于 S S S 类型的每个对象 o 1 o_1 o1,都有一个 T T T 类型的对象 o 2 o_2 o2,使得对于根据 T T T 定义的所有程序 P P P,当 o 1 o_1 o1 替换为 o 2 o_2 o2 时, P P P 的行为保持不变,则 S S S 是 T T T 的子类型。
4. 参考
https://www.usingenglish.com/forum/threads/substituted-by-substituted-fo-substitution-of-for.98412/
-
substitute + for
(1) substitute A for B – this means A takes the place of B – use A
(2) substitute B for A – B takes the place of A – use B
(3) B was substituted for A – B takes the place of A – use B
(4) A was substituted for B – A takes the place of B – use A -
substitute + with/by
(1) substitute A with/by B – B takes the place of A – use B
(2) substitute B with/by A – A takes the place of B – use A
(3) A was substituted with/by B – B takes the place of A – use B
(4) B was substituted with/by A – A takes the place of B – use A