go语言抽象工厂设计 go 抽象类( 四 )


典型的例子是:Qt中的数据库模块就利用了工厂模式 , 封装了数据库的底层实现 。在保持数据库用户接口不变的情况下,通过更换数据库驱动,可以实现数据库类型无缝切换 。
在需求趋于稳定时使用,需求不稳定时,不要过度设计,否则设计很容易被推翻 , 白费力气 。
从设计模式的本质来看,工厂模式:
先看例子: 抽象工厂模式 。
由前面工厂模式可知,所有的“工厂”有一个共同点:每个工厂都会提供创建对象的函数 。既然所有工厂都实现了同一类功能,那么我们可以为工厂抽象出一个公共接口(虚基类),此接口定义了创建工厂子类的功能 。这种场景是否似曾相识?是的,工厂和工厂的功能接口构成了使用工厂模式的场景 。即工厂本身也适用于工厂模式 。使用工厂模式来设计工厂,必然要写一个生产工厂的工厂 。生产工厂的工厂 , 返回值是工厂的抽象接口类 , 所以这种设计模式叫“抽象工厂模式” 。其实,笔者觉得把这种设计模式叫做“工厂工厂模式”更容易理解 。
如果只有一个工厂就不要使用抽象工厂模式了,只有在工厂很多时,才使用抽象工厂模式 。
需求不稳定时,不要过度设计,一切都可能被推翻 。对于小的项目,不需要过度追求使用设计模式 , 架构的代码最好只占整个项目代码的一小部分,否则就是主次颠倒 , 给自己找麻烦 。对于大的项目,在需求较稳定的情况下,为了提高可维护性、扩展性,可以考虑使用设计模式 。另外 , 抽象工厂模式有一定的理解难度,要考虑你设计的代码,其他人是否能够读懂,简单易懂也是需要考虑的方面 。
所以,从设计模式的本质来看,
先看例子: 单例模式 。
上面的例子都是允许一个类被创建多次的 。如果我们想要限制一个类只被创建一次,即只有一个全局可访问的实例(和C语言中的全局变量一样),例如应用程序对象,每个应用程序都应该只有一个应用程序对象 。此时应该怎么编写代码呢?
答案还是封装 。把不想暴露出来的信息藏起来,把必须暴露的信息暴露出来 。单例模式把类的构造函数设置成private私有访问权限,限制外部无法通过new来创建实例 。只能通过特定的接口来获取实例指针 。需要提及的是,封装时需要考虑多线程安全的问题 。
当一个类需要有多个实例存在时,不使用单例模式 。
从设计模式的本质上看,
具体的例子和写法,可以参考菜鸟教程中的 建造者模式 。
建造者模式的典型使用场景是快餐店的套餐搭配模型 。套餐由若干个单个餐品组合而成 。单个餐品又由不同的原材料构成 。这种层层组合的树形对象关系的应用场景下,为了创建顶层的对象,需要先一层层的创建底层的对象 , 逐步向上,直到构造出根对象 。这种场景下,使用继承可以将同类的对象关联起来 , 使用组合可以将不同类型的对象组合起来 。组合就是把不同对象放在一块内存中保存,作为一个整体使用 。
完全使用继承来解决此类问题是非常不提倡的 。设计模式理论中有一个原则是:“少用继承,多用组合” 。因为继承是一种强耦合 , 组合是一种松散的耦合 。耦合不利于适应需求变化 , 是项目中的一颗定时炸弹 。
从设计模式的本质上看,
菜鸟教程中没有提及的一种设计模式是组合模式 。具体内容可以参考: 第四节:组合模式和建筑者模式详解 。
这里简单说明一下 , 组合模式和建造者模式比较像 , 也是遵循树形对象关系结构 。和建造者模式相比,不同之处在于 , 子对象和父对象具有相同的类型 。所以可以说 , 组合模式是简单的建造者模式 。

推荐阅读