每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心
设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案
面向对象设计模式描述了面向对象设计过程中,特定场景下,类与相互通信的对象之间常见的组织关系
GoF23中设计模式
好的设计模式是那种可以满足”应对变化,提高复用“的设计
敏捷软件开发:源代码就是设计。
面向对象三大机制:
封装,隐藏内部实现
继承,复用现有代码
多态,改写对象行为
通过面向对象语言OOPL认识到的面向对象并不是面向对象的全部。
对于不同员工计算工资的方式不同的问题:
如果用结构化做法:
enum EmployeeType{
Engineer;
Sales;
Manager;
...
}
//计算工资
if(type == EmployeeType.Engineer){...}
else if (type == EmployeeType.Sales){...}
如果用面向对象的做法:
abstract class Employee{
...
public abstract int GetSalary();
}
class Sales: Employee{
...
public override int GetSalary(){...}
}
class Engineer: Employee{
...
public override int GetSalary(){
...
}
}
//显示工资程序
Employee e = emFactory.GetEmployee(id);//在这个GetEmployee里面会根据id所对应的是那种类型,不如说是销售人员,就new一个销售人员
MessageBox.show(e.GetSalary());
所以说面向对象不能杜绝改变,但是它能够降低改变的影响
现在需求改变了,由于公司业务的拓展,又出现了更多类型的员工,这对认识管理系统提出了挑战--原有程序必须改变
结构化做法:
几乎所有涉及到员工类型的地方(当然包括”计算工资程序“)都需要做改变。。也就是所有if else 都需要多一些else if,这些代码都需要重新编译,重新部署。。
面向对象做法:
只需要在新的文件里增添新的员工类,让其继承自employee抽象类,并重写GetSalary()方法,然后在EmployeeFactory.GetEmployee方法中根据相关条件,产生新的员工类型就可以了。其他地方(显示工资程序,Engineer类,sales类等),则不需要做任何改变。。
所以面向对象最大好处就是新增员工类型不会影响原来员工类型的实现代码。。
从设计原则到设计模式:
1针对接口编程,而不是针对实现编程
2优先使用对象组合,而不是类继承。。类继承是增加耦合的,因为很多东西都是从父类拿来的,类继承通常称为白箱复用。对象组合是黑箱复用。继承在某种程度上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。只有明显的is a关系才使用继承,平时优先使用组合。
3封装变化点,使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不会对另一侧产生不良影响,从而实现层次间的松耦合。
4使用重构得到模式--设计模式的应用不宜先入为主
几条更具体的设计原则:
单一职责原则(SRP):一个类应该仅有一个引起它变化的原因。
开放封闭原则(OCP):类模块应该是可扩展的,但是不可修改(对扩展开放,对更改封闭)
Liskov替换原则(LSP):子类必须能够替换他们的基类
依赖倒置原则(DIP):高层模块不应该依赖底层模块,二者都应该依赖于抽象。抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
接口隔离原则(ISP):不应该强迫用户依赖于他们不用的方法