架构师训练营 Week 02 总结

用户头像
Wancho
关注
发布于: 2020 年 06 月 17 日

面向对象设计的基本原则

OOD(Object-Oriented Design)

软件设计的终极目标是,“高内聚,低耦合”,从而使软件通过扩展来应对变化。

1 开/闭原则

OCP(Open/Close Principle)

对扩展是开放的(Open for extension),对改变是封闭的(Closed for modification)。即是不修改现有的类(或者模块、函数),而通过增加类来实现新的功能。

1.1 范例

有一个电话机系统,Button的类型有数字键、Send键等,Dialer负责拨号等任务。

为实现每个按钮实现不同功能,可以使用观察者模式+适配器模式,Button使用ButtonListener接口处理OonPressed事件,然后实现各种Adapter适配器,由适配器去调用Dialer中相应的函数。

最后使用Phone类来组装

public class Phone {
private Dialer dialer;
private Button[] digitButtons;
private Button sendButton;
public Phone() {
dialer = new Dialer;
digitButtons = new Button[10];
for (int i = 0; i < digitButtons.length; i++) {
digitButtons[i] = new Button();
final int digit = i;
digitButtons[i].addListener(new ButtonListener() {
public void buttonPressed() {
dialer.enterDigit(digit);
}
});
}
sendButton = new Button();
sendButton.addListener(new ButtonListener() {
public void buttonPressed() {
dialer.dial();
}
});
}
}

2 依赖倒置原则

DIP(Dependency Inversion Principle)

高层模块不能依赖底层模块,大家都依赖抽象;抽象不能依赖实现。

这是各种框架使用的技巧,框架所支持的功能都有顶层定义,亦由顶层按定义好的规则来调用。

这里需要注意的是,接口必须是在高层,绝不是底层自己抽象自己。

2.1 范例

这里有个直观的系统框架,层次分明,但

这是个典型的反例,从高层到底层,均依赖底层组件。也许实践中更糟糕的是,相互依赖。

现在从底层实现中抽象出接口,供高层调用。

3 Liskov替换原则(LSP)

一个关于正确继承的规则

言道,静态语言中,实现OCP的关键在于抽象,而抽象的威力在于多态和继承。

3.1 规则

子类不能比父类更严格,不符合IS-A一定不符合LSP

LSP要求,凡是使用基类的地方,一定也适用于其子类。

不适合继承的,应该改成组合。

3.2 举例

有Rectangle包含width和height,又有Square只需要side。

正方形IS-A长方形码?

Rectangle能够接受不同的长宽,而Square则不能,这将会导致:

Rectangle rect = new Square();
rect.setWidth(3);
rect.setHeight(4);
assert(12 == rect.calculateArea());

从平时的认识中,正方形是长方形的特例,但正方形比长方形更严格了,所以正方形不应该继承于长方形。也许可以为它们抽象出共性的基类:

4 单一职责原则

SRP(Single Responsibility Principle)

又称为内聚性原则(Cohesion),一个模块的组成元素之间的功能相关性。

4.1 原则

一个类只能有一个引起它变化的原因;当它要变化的时候,这个类的整体是一起行动的

4.2 举例

Rectangle类包含两个职责:draw()和area()

Computational Geometry Application,利用Rectangle计算面积;Graphical Application利用Rectangle绘制长方形,也需要计算面积

存在的不足是:脆弱,把绘图和计算功能耦合在一起,当修改其中一个时,另一个功能可能会意外受损;不可移植,Computational Geometry Application只需要使用area(),却不得不包括GUI的依赖。

在Rectangle的基础上,再抽象出area()接口,可以达成解area()与draw()耦合,使用它们更加稳定。

5 接口分离原则

ISP(Interface Segregation Principle)

不应该强迫客户程序依赖它们不需要的方法(不对用户开放不必要的接口)

开放过程应该为:接口->测试代码->实现



相关书籍

《敏捷软件开发--原则、模式与实践》



用户头像

Wancho

关注

还未添加个人签名 2020.02.28 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 Week 02 总结