大话设计模式读书笔记-15抽象工厂模式

bigtalk.jpg

第15章 就不能不换DB吗?——抽象工厂模式

概念

定义多个创建接口可以创建多套产品,每套产品有不同的实现方案(子类)。

通过产品、方案的概念,进一步增强了工厂模式(维度的提升),工厂模式,理解为为了创建同一套产品的不同方案而诞生的模式;抽象工厂模式可以适用于不同产品不同方案,创建的各种子类不再仅限于一套产品,因此抽象工厂类、以及相应工厂子类中的创建接口不止一个,即:每一个类接口对应一套产品,每个工厂类代表一套方案。

实现

抽象工厂模式实现图如下:

img

对比:简单工厂模式、工厂模式、抽象工厂模式

  1. 简单工厂模式:定义简单工厂,简单工厂通过分支的方式创建不同种类的对象。(SimpleF->CreateByTool(x))
    • 简单工厂模式实现端:封装了对象创建过程,但不满足开放封闭原则。
    • 简单工厂模式客户端:指定具体简单工厂类;指定具体简单工厂类参数指明对象类型;通过具体简单工厂类接口创建对象;

例子:定义不同版本的一套对象,(如:加、减、乘、除,都是运算符,或者某个数据表用SQL,MySQL等实现都是同一个表),简单工厂中增加分支支持创建不同操作;客户端需要知道具体工厂类以及其接口。

  1. 工厂模式:定义抽象工厂描述公共创建接口;再定义具体工厂子类继承抽象工厂;运用具体工厂,创建具体类型。(F->ToolxF->CreateByTool())
    • 实现端:封装并隔离对象创建,满足开放封闭。
    • 客户端:指定具体工厂类;使用抽象工厂类创建对象;

例子:定义不同版本的一套对象,(如:加、减、乘、除,都是运算符,或者某个数据表用SQL,MySQL等实现都是同一个表),通过增加具体工厂类,支持不同操作;客户端只需要知道具体工厂类。

  1. 抽象工厂模式:(F->ToolxF->CreateByTool_product1,CreateByTool_product2)

    抽象工厂模式:与工厂模式同,不同在于工厂模式创建的不同对象只有一套功能(如加减乘除只能是算数运算符),抽象工厂模式创建的不同对象可能是其它的产品(如除了包括各运算符子类的算数运算,还有各运算符子类的软件操作)。特点是,具有多个实现方案(比如数据库的SQL/MySQL…),的不同产品(如数据库中的各种表),工厂模式可用于一个产品(比如多个数据库方案中的一个表),但是如果工厂模式中再增加接口用于多个表,那工厂模式就变成了抽象工厂模式。

    例子:定义不同版本的多套对象,(如:某个表用SQL,MySQL等实现,另外的表同样如此,总之是不同的表用不同的方案),通过增加具体工厂类,支持不同操作,通过增加工厂类接口,支持不同套操作。

上面将数据库、运算符号的例子中,我们通过“方案”、“产品”的概念这样理解:

  • 实现方案的定义:比如数据库中的MySQL、Oracle,或者运算符中的加、减。
  • 实现的不同产品:比如MySQL或Oracle中的某个部门表,或者加法或减法的某种含义(比如算数运算、字符串拼接等)

抽象工厂模式演化

抽象工厂模式的特点

优点:可以灵活增加新的实现方案(不同的子工厂,纵向),以及新的产品(一个工厂内的不同创建函数,横向),达到开放封闭性原则。
缺点:增加一个产品,需要修改很多类(每个方案都要支持该产品);如果更改产品的实现方案,而且所有创建产品的地方都需要修改成相应的类。

改进抽象工厂方法:类简单工厂替代抽象工厂模式。

将不同实现产品放到简单工厂产品函数switch分支中集中创建,并且提前设置好产品实现方案,不用再客户端中参数指定了。

改进方法的特点:
通过简单工厂模式,避免了抽象工厂增加产品时过多类的创建和修改;通过提前预设简单工厂模式参数,不用在客户端指定具体实现了;但是还是需要在增加产品和实现方案的时候,修改到简单工厂类里面去。

进一步改进缺点:结 合反射进行。

前面改进的简单工厂模式,可以通过反射的方式,去除掉switch分支。

假设switch分支分别为:new SQLxxx; new Accessxxx; new Oraclexxx;
通过反射,用字符串替代变成:new <dbname>xxx; 这样,只要一个带有变化的 <dbname> 字符串变量取代具体的类名,就取出了switch分支。

反射通过字符串变量的方式指定类名,而正常是直接指定类名,这样,反射因为字符串是变量,所以更灵活,更容易修改。

当前的缺点:每次增加实现方案,不需要修改每个产品创建函数分支增加实现方案了,但是还是需要修改最开始的实现方案静态字串成员。

进一步完善反射:将反射中变化的字符串部分,直接写到配置文件中,代码中读取

将反射的字符串,写成配置文件,这样就可以避免切换产品实现的时候,修改类名了,只需要修改相应配置文件,然后类中会自然将相应的实现名称读取到类中,创建相应的对象。

总结

  • 简单工厂模式:情况一个抽象类(代表一类产品),不同具体子类(产品不同的实现方案)。一个工厂(生产一个产品),分支(方案)创建不同子类(该方案产品);客户端指定参数确定分支(方案名),增加子类(方案)需修改工厂。
  • 工厂模式:情况一个抽象类(代表一类产品),不同具体子类(产品不同的实现方案)。一个抽象工厂(生产一个产品),具体工厂(方案)创建不同子类(该方案产品);客户端指定具体工厂(方案类)创建子类(产品),增加子类只需增加工厂(方案)不用修改工厂接口。
  • 抽象工厂模式:情况多个抽象类(代表不同产品),各自不同具体子类(各自不同的实现方案)。一个抽象工厂(生产多个产品),具体工厂创建不同子类(不同方案),具体工厂内不同函数创建不同抽象对象(同一方案的不同产品);客户端指定具体工厂(方案)创建子类(产品),通过具体函数(产品需求)创建不同类别集(产品),增加类别集(不同产品)、子类(方案)都需要修改关联的工厂类(方案)。

这样理解:抽象类可以理解成数据库表,不同具体子类可以理解成不同类型数据库实现的表数据(SQL/MySql等);工厂理解成创建特定类型数据表的工具;

  • 简单工厂模式:相当于需要一个数据表,简单工厂创建数据表理解成用分支创建不同实现的数据库表。
  • 工厂模式:相当于需要一个数据表,工厂创建数据表理解成用特定子类工厂创建对应实现数据库的表。
  • 抽象工厂模式:相当于需要多个数据表,工厂创建某数据表理解成用特定子类工厂对应实现数据库、其中的特定函数对应这个表,创建另一个表理解成用相同类另一个函数创建对应表。

抽象工厂问题:每个类都需要很多函数创建不同的表,每增加一个数据库实现都需要创建包含很多对应表函数的类(这个尚未破坏封装性);每增加一个表都需要修改每个已有实现增加对应表函数(这个破坏了封装性修改很多地方)。

改进抽象工厂:创建不同抽象类,回归到简单工厂模式分支中创建不同数据库实现,不同表仍然不同函数。这样不用增加类了。提前将实现写成静态成员就不用指定参数了,用反射表示实现名就不用分支了,用配置描述实现名读取到反射机制中也不用增加实现时修改静态成员了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,710评论 4 376
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,839评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,295评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,776评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,198评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,074评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,200评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,986评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,733评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,877评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,348评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,675评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,393评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,209评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,212评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,003评论 2 280

推荐阅读更多精彩内容