UML(统一建模语言)
- 用例图:给用户看的,测试人员据此编写测试用例。一个用例(usecase)就是一个功能。用例图中的泛化关系(generalization)类似于各个类之间的继承关系,用空心箭头表示;包含关系(include),虚线表示;扩展关系(extend):在用例执行过程中通过一些条件触发另一些功能,类似于程序执行中的条件判断;
- 类图:给开发人员看的,很重要。泛化关系(is a kind of)、实现关系(抽象类和实现类之间的关系)、依赖关系(一个类没有另一个类作为成员变量却还使用另一个类,用虚线表示)、关联关系(一个类有另一个类作为成员变量并且使用它,关联关系是通过使用成员变量来实现的,用实线表示)、聚合关系(更强的关联关系,整体和部分之间的关系,也是通过成员变量来实现的)、组合关系(最强的关联关系,部分不仅组成整体而且属于整体)。
- 时序图:表示一个对象的生命周期中的所有活动。
- 活动图:类似于流程图,开发人员据此写业务代码,其中泳道的概念很重要,划分出各个不同的活动对象。
- 状态图:通过建立对象的生存周期模型来描述对象随时间变化的动态行为。
设计模式
内功:数据结构、算法、设计模式、重构、软件工程。
各种设计模式原则的最终目标:高内聚、低耦合。
原则
- 单一职责:每个类的功能尽可能单一,即高内聚。
- 开闭:修改或添加新功能时,以前写好的代码不要再修改了,而是要添加新代码。好处:一是提高了代码的可维护性;二是提高了安全性;三是提高了可读性;四是提高了可复用性。
- 里氏代换:任何抽象类出现的地方都鼓励用其实现类替换,也即鼓励使用多态。
- 依赖倒转:依赖于抽象接口,不依赖于具体实现,也即针对抽象接口编程。代码设计分为三层:高层业务逻辑层、中间抽象层、下层实现层。抽象层把业务逻辑层和实现层隔离,即解耦合,各自修改代码互不影响。设计实现功能时首先从中间的抽象层开始着手。
- 接口隔离:接口函数的功能也要单一,即没必要用到的虚函数就不必实现了。
- 合成复用:如果继承和组合都能完成功能的添加,那么优先使用组合(组合细分为依赖、关联、聚合、组合),因为相互继承的类之间的关联性很强,尤其子类会把父类的所有方法都继承过来,而有些是不必要的,违反了接口隔离原则,并且父类的任何修改都会影响到子类,也不符合低耦合的设计目标。
- 迪米特法则(知道最少):采用中介的形式,可使各个模块之间的耦合度降低。例
如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实现。这样其他模块不需要了解另外一个模块的内部实现细节,因此当一个模块内部的实现发生改变时,不会影响其他模块的使用。(黑盒原理)这个统一的接口有点类似一个局部网络中交换机的角色。
模式
简单工厂模式:
- 实现了对象创建和使用的分离;不过对工厂职责过重,一旦不能工作,系统会受到影响,而且系统中类的个数会增多,相应地复杂度会增加;违反开闭原则,增加新产品需要修改工厂逻辑,使得工厂越来越复杂。综上,该模式适用于创建对象比较少的场景,客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
- 构造函数不要太复杂,功能要单一,只需要创建对象即可。
工厂方法模式:
- 由于简单工厂模式违反了开闭原则,即每次要添加新的任务时总是要修改工厂的代码,这样一来工厂的代码和逻辑量就会越来越大,由此就有了改进的工厂方法模式。即:
简单工厂模式 + 开闭原则 = 工厂方法模式
- 可能在生产一个具体产品时有很多的细节问题需要处理,此时就可以在具体工厂创建具体产品时来处理,而在主函数中生产一个具体产品时只需面向抽象工厂接口来编程即可,生产产品的具体细节在具体工厂中已经包装好了,这样就可使得生产产品的过程和主函数的业务逻辑隔离,即解耦合。
抽象工厂模式:
- 工厂方法模式虽然解决了开闭原则的问题,但随着生产的产品数越来越多,相应的产品类也会越来越多,因此考虑避免写太多的功能单一的产品类,而是改写产品类使其生产一类特征相似的产品,即产品族。
- 抽象工厂模式针对产品族是符合“开闭原则”的,而针对产品等级结构是不符合“开闭原则”的。
- 抽象工厂模式适用于系统中有不止一个产品族并且产品等级结构稳定的场景。而如果要增加新的产品等级结构则很麻烦,需要对原有系统进行较大修改,甚至要修改抽象层代码,这违背了“开闭原则”。
总结三种工厂模式:
简单工厂模式 + “开闭原则” = 工厂方法模式
工厂方法模式 + “产品族” = 抽象工厂模式
简单工厂模式适合规模较小的模型
工厂方法模式适合中等规模的模型
抽象工厂模式适合复杂的产品等级和产品族
单例模式
- 在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。