最近王阳明好火
LKP aka LoD - Law of Demeter 德墨忒尔原则,『孤独的德墨忒尔』。调用者不应该知道非直接依赖的实现细节,从而达到低耦合目的。耦合意味着依赖即模块间的紧密程度,耦合越高系统越难维护。
this principle states that an object should never know the internal details of other objects. It was designed to promote loose coupling in software designs.
The more the coupling between the components in an application, the harder it becomes to modify and maintain it over time.
好处
- 减少依赖:reduces dependencies and
- 低耦合:helps build components that are loose coupled for code reuse
- 灵活具备弹性和可扩展性:promotes flexibility and adaptable to future changes
- 自然具备可维护性:easily maintainable and
如何实现
调用者若需要关心非直接依赖的实现细节,就会导致系统很脆弱,将来修改细节将影响调用者,通过封装可解决 encapsulation to reduce coupling amongst the components of your application。
Bad
页面 A 通过 url 传参到页面 B。
发送端:
// 页面 A
const encoded = encodeURIComponentSafely(jsonStringifySafely(detailInfo));
const path = `pages/b/index?detailInfo=${encoded}`;
jump(path);
接收端:
// 页面 B
// 小程序自己解析了,无需再次 encodeURIComponent
const parsed = jsonParseSafely(query.detailInfo);
Good
这其实是序列化和反序列化(serialize、deserialize),是通用能力封装成函数更合适,以后传输对象都会用到。源头序列化成字符串到接收的时候反序列化成对象。
好处:第一细节屏蔽,最小知识原则,假如以后更改了底层的序列化和反序列化方法,使用者无需感知,其次二者其实是一个 pair 的关系,用序列化反序列化术语描述让其理解成本更低,比如我源头调用 serialize 了,那我必定要在接收端 derialize,而无需像现在这样,我得仔细观察发送端用了什么算法,哦,那我接收端相应的用什么反解掉。我还得注意,小程序自己就解析了,无需我再次 decode 了,这些知识都封装到函数里面,调用者无需关心。
// lite-lodash.ts
export const json {
serialize: (obj: Record<string, any>): string => {
return encodeURIComponentSafely(jsonStringifySafely(obj));
},
deserialize: (json: string): Record<string, any> => {
// 不依赖小程序自行会 decode,是得其更通用
return jsonParseSafely(decodeURIComponentSafely(json));
},
}
// 页面 A
const encoded = json.serialize(detailInfo));
const path = `pages/b/index?detailInfo=${encoded}`;
jump(path);
// 页面 B
// 小程序自己解析了,无需再次 encodeURIComponent
const parsed = json.deserialize(query.detailInfo);