亡羊补牢,为时不晚。
这本书是真的抽象,看的头都疼。。。
补充记录一些以前没有学过的小Tip。
教材:《设计模式 可复用面向对象软件的基础》 第一章
定义:
零、设计模式
设计模式代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。
一、构建用户界面的三元组MVC
M:Model,Model是应用对象
V:View,View是它在屏幕上的表示。
C:Controller,Controller定义用户界面对用户输入的响应方式。
MVC将用户界面设计分离以提高灵活性与复用性。
二、模式依据其目的可分为三类:
创建型:创建型模式与对象的创建有关。
结构型:结构型处理类或对象的组合。
行为型:行为型模式对类或对象怎样交互和怎样分配职责进行描述。
三、模式指定范围:
类模式:处理类与子类的关系,是静态的,在编译时刻就已经确定了。
对象模式:对象模式处理对象间的关系,这些关系在运行时刻是可以变化的更具有动态性。
几乎所有的模式都使用继承机制。
大部分的模式都是属于对象模式的范畴。
四、类的继承与对象的组合对比。
继承(is-a 关系)
c++类的继承例子:
class A; // 定义省略
class B : public A {
...
}
B b;
其中B是A的子类,A是B的supertype
组合(has-a 关系)
c++类的组合例子:
class A; // 定义省略
class B{
...
A a;
}
B b;
对比:
当需要复用子类时,实现上的依赖性就会产生一些问题。如果继承下来的实现不适合解决新的问题。则父类必须重写或被其他更适合的类替换。
组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口。这其实是会产生良性结果的:
(1)因为对象只能通过接口访问,所以我们并不破坏封装性。
(2)只要类型一致,运行时刻可以用一个对象来代替另一个对象。
(3)因为对象是基于接口写的,依赖关系很少。
因此有:
面向对象设计的第二原则:
优先使用对象组合,而不是类继承。
五、抽象类与override
抽象类:有未实现的虚函数,子类来实现,方便实现多态。
override:试图重写父类中已经实现的方法,子类使用override覆盖实现。
六、参数化类型
参数化类型允许你在定义一个类型时并不指定该类型用到的其他所有类型,未经指定的类型在使用时以参数形式提供。如c++的template。
继承:允许你提供缺省实现。
对象组合:允许你在运行时刻改变被组合的行为。但是它存在间接性,比较低效。
参数化类型:允许你改变类所用到的类型。
七、关联运行时刻和编译时刻的结构
聚合:意味着一个对象拥有另一个对象或者对另一个对象负责。
聚合意味着聚合对象和其所有者具有相同的生命周期。
相识:意味着两个对象之间只有”关联“或者”引用“关系。
它只标记了对象间较松散的耦合关系。
八、常见的设计失误导致需要重构
(1)没有面向接口的约束设计类,而是面向实现设计类。
(2)对于特殊的操作,把操作写死了。
(3)对软硬件平台依赖,难移植。
(4)对对象的表示或者实现的依赖。
(5)设计的算法不可被扩展、优化替代。
(6)紧耦合。为了删改一个类,需要同步修改很多其他的类。
(7)通过生成子类来扩充功能,不但需要理解父类代码,还会代码量暴涨,类爆炸。
(8)对类的修改,会涉及很多子类的变动。
九、常见的设计场景灵活性侧重点
(1)应用程序
内部复用性:确保不会做多余的设计和实现;
可维护性;
可扩展性。
(2)工具箱
代码复用:因为工具箱是面向对象环境的子程序库;
不知道特殊的需求:避免假设和依赖;
效率。
(3)框架
框架规定了你的应用的体系结构。它定义了整体结构,类和对象的分割,各部分的主要责任,类和对象怎么协作,以及控制流程。
预定了设计参数,以便于应用开发者集中于应用本身的特定细节,注重设计复用;
应用对框架结构的变化是极其敏感的,松散耦合很重要;