博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
<抽象工厂>比<工厂方法>多了啥(区别)
阅读量:5160 次
发布时间:2019-06-13

本文共 1717 字,大约阅读时间需要 5 分钟。

前言:仅当复习讨论,写得不好,多多指教!

710776-20190305213321719-2025047897.png

上一篇文章《》介绍了简单工厂模式和工厂方法模式。本篇文章则讲最后一个工厂----抽象工厂。如果对工厂方法比较模糊的,可以返回上一篇文章复习。接下来先看故事。

抽象工厂模式

UML

  又经过三年之后,中国已经越来越国际化了,很多日本人来中国留学也带来了本土的猫和狗。一旦他们留学回去之后,就把这些动物送到了动物流浪工厂中。此时,个别对小日本有抵触的人并不想为这些日本的动物喂食,于是拉起一部分人到工厂去抗议,要求自己的食物只给中国的动物吃,把日本的动物赶出去。厂长一看这么多人抗议,没办法,只能把动物分国籍了,于是把中国流浪动物在一个工厂,日本流浪动物在另外一个工厂。

  某一天,一位本来认为日本的动物也是动物的爱心人士看到了安培晋三参拜靖国神社的新闻,于是她要求原来喂养的日本流浪动物 切换 到中国流浪动物,如下图所示,她只要切换一个工厂就可以达成心愿。
710776-20190305230653995-157423802.png

对比一下业务场景

710776-20190306000629162-924791525.png

概念

  抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。(如上图,提供了数据库抽象工厂,而无需指定具体数据库给客户端)

优点

  1. 最大的好处就是易于交换产品体系(sqlserver 替换成 oracle),由于具体工厂类,例如sql server工厂在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的配置。
  2. 它让具体的创建实例过程与客户端分离,客户单是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中(比如sqlserverUser, 客户端只知道抽象类,不关心你是用sql server还是用oracle来实现。全部都依赖抽象,符合依赖倒置原则)

缺点

  1. 如果更换 产品体系,改动的工作量非常大,因为到处都有 IFactory factory=new SqlserverFactory()的实现。这么实例化1000次,就要改1000次。
  2. 增加一个功能,要涉及到增加三个类和修改三个工厂,这。。。比较累人。

改进

  针对以上两个问题,来进行解决。1.可不可动态实例化?2. 增加类是可扩展的,但是修改三个工厂是否可以去掉?

  答案是:可以的,利用反射+配置文件

UML

  我们将工厂干掉,利用数据库Context类来动态实例化具体的功能类(产品类)。利用反射来实例化相关的实例,而不是让工厂去实例化,实例化格式如下:

  Assembly.Load(“程序集名称”).CreateInstance(“命名空间.类名称”)

710776-20190306001638392-1232564161.png

客户端实现方式

数据库Context代码如下:

class 数据库Context{    private static readonly string db=ConfigurationManager.Appsettings["DB"];    private static readonly string AssemblyName="程序集名称";    public static IUser 增加用户()    {     string className=AssemblyName+".User";     return  (IUser)Assembly.Load(AssemblyName).CreateInstance(className);    }  //其他类似}

总结

介绍完了抽象工厂模,但是它跟工厂方法的差异在哪里?

  1. 每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。
  2. 工厂方法模式是一定要利用工厂抽象类的,这个是包含在它的定义中的。而抽象工厂模式进阶中已经干掉了抽象工厂类,去利用反射进行实例化。
  3. 在实际项目中,更换数据库是有可能的, 比如某个数据库提供商在数据量大的时候不够稳定,此时经过商讨,要更换数据库提供商,这里就涉及到很大的扩展性问题了。

转载于:https://www.cnblogs.com/zhan520g/p/10479919.html

你可能感兴趣的文章
Hadoop HBase概念学习系列之HBase里的宽表设计概念(表设计)(二十七)
查看>>
Kettle学习系列之Kettle能做什么?(三)
查看>>
Day03:Selenium,BeautifulSoup4
查看>>
awk变量
查看>>
mysql_对于DQL 的简单举例
查看>>
35. Search Insert Position(C++)
查看>>
[毕业生的商业软件开发之路]C#异常处理
查看>>
一些php文件函数
查看>>
有关快速幂取模
查看>>
Linux运维必备工具
查看>>
字符串的查找删除
查看>>
NOI2018垫底记
查看>>
快速切题 poj 1002 487-3279 按规则处理 模拟 难度:0
查看>>
Codeforces Round #277 (Div. 2)
查看>>
【更新】智能手机批量添加联系人
查看>>
NYOJ-128前缀式计算
查看>>
淡定,啊。数据唯一性
查看>>
深入理解 JavaScript 事件循环(一)— event loop
查看>>
Hive(7)-基本查询语句
查看>>
注意java的对象引用
查看>>