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

![](https://img2018.cnblogs.com/blog/710776/201903/710776-20190305213321719-2025047897.png)
> 上一篇文章《[比多了啥](https://www.cnblogs.com/zhan520g/p/10461094.html)》介绍了简单工厂模式和工厂方法模式。本篇文章则讲最后一个工厂----抽象工厂。如果对工厂方法比较模糊的,可以返回上一篇文章复习。接下来先看故事。

抽象工厂模式

### UML
  又经过三年之后,中国已经越来越国际化了,很多日本人来中国留学也带来了本土的猫和狗。一旦他们留学回去之后,就把这些动物送到了动物流浪工厂中。此时,个别对小日本有抵触的人并不想为这些日本的动物喂食,于是拉起一部分人到工厂去抗议,要求自己的食物只给中国的动物吃,把日本的动物赶出去。厂长一看这么多人抗议,没办法,只能把动物分国籍了,于是把中国流浪动物在一个工厂,日本流浪动物在另外一个工厂。
  某一天,一位本来认为日本的动物也是动物的爱心人士看到了安培晋三参拜靖国神社的新闻,于是她要求原来喂养的日本流浪动物 切换 到中国流浪动物,如下图所示,她只要切换一个工厂就可以达成心愿。
![](https://img2018.cnblogs.com/blog/710776/201903/710776-20190305230653995-157423802.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(“命名空间.类名称”)

客户端实现方式

数据库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. 在实际项目中,更换数据库是有可能的, 比如某个数据库提供商在数据量大的时候不够稳定,此时经过商讨,要更换数据库提供商,这里就涉及到很大的扩展性问题了。

<抽象工厂>比<工厂方法>多了啥的更多相关文章

  1. iOS常用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

    1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂方法包含:父类拥有共同基础接口,具体子类实现子类特殊功能,工厂类根据参数区分创建不同子类实例.该场景对应的UML图如下 ...

  2. iOS经常使用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

    1. 简单工厂模式 怎样理解简单工厂,工厂方法. 抽象工厂三种设计模式? 简单工厂的生活场景.卖早点的小摊贩.他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂.它生产包子,馒头,地沟油烙的煎饼. ...

  3. <工厂方法>比<简单工厂>多了啥

    前言:多注重设计.仅当复习讨论! 简单工厂模式 UML图   假如有一位爱心人士,想给饥饿的流浪动物喂食.此时爱心人士身带了狗粮,但是他到处找啊找,最终只找到了猫大人,是不是有点惨兮兮.但是如果有简单 ...

  4. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  5. 简单工厂模式,工厂方法模式,抽象工厂模式,spring的狂想

    菜鸟D在项目中遇见一个比较纠结的高耦合,所以就想办法来解耦.情况是这样的:系统通过用户选择treeview控件的节点判断调用不同的处理,这些处理中某些东西又是类似的.同事的建议是采用简单工厂,耦合就耦 ...

  6. Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式

    工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...

  7. 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  8. 第四十篇 Python之设计模式总结-简单工厂、工厂方法、抽象工厂、单例模式

    一. 简单工厂 简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 简单工厂的用处不大,主要就是一个if... ...

  9. 结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别

    之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个 ...

  10. Java设计模式之简单工厂、工厂方法和抽象工厂

    在前面的学习中(参见前面的博客),我们学到了很多OO原则: 封装变化 多用组合,少用继承 针对接口/超类编程,不针对实现编程 松耦合 开闭原则 让我们从一个简单的类开始,看看如何将之改造成符合OO原则 ...

随机推荐

  1. vueX、vue中transition的使用、axios

    引入一篇好文章链接:看一遍就会的vuex文章;完!!! vue中transtion的使用:transition文章;完!!! axios的文章:axios;完!!!

  2. vue-cli 创建项目失败

    vue-cli 创建一个vue项目报错 npm code 404. 尝试解决方法都有,我是第3种方法生效 更新npm 重新安装nodejs vue-cli@3.0.1 在创建项目的时候,不能开启其他v ...

  3. 多线程深入:乐观锁与悲观锁以及乐观锁的一种实现方式-CAS(转)

    原文:https://www.cnblogs.com/qjjazry/p/6581568.html 首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每 ...

  4. table-cell width:1% 深入理解

    问题描述 今天在使用Bootstrap给页面添加底部导航栏时,需要在手机下也使导航栏呈现水平排列的效果.最后在网上查找解决方法是,看到这样一个解决方法: .nav-justified > li ...

  5. 原生js 基于canvas写一个简单的前端 截图工具

    先看效果 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...

  6. Cocos Creator 监听安卓屏幕下方返回键

    addEscEvent = function(node){ cc.eventManager.addListener({ event: cc.EventListener.KEYBOARD, onKeyP ...

  7. python爬虫简单的添加代理进行访问

    在使用python对网页进行多次快速爬取的时候,访问次数过于频繁,服务器不会考虑User-Agent的信息,会直接把你视为爬虫,从而过滤掉,拒绝你的访问,在这种时候就需要设置代理,我们可以给proxi ...

  8. 字节转化为结构体BytesToStruct

    //结构体转字节数组 public byte[] StructToBytes (object structObj) { int size = Marshal.SizeOf (structObj);// ...

  9. jpa报错:Table 'dev-test.hibernate_sequence' doesn't exist

    Hibernate 能够出色地自动生成主键.Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略.其生成规则由@GeneratedValue设定的.这里的@id和 ...

  10. 2017-2018-2 20155228 《网络对抗技术》 实验八:Web基础

    2017-2018-2 20155228 <网络对抗技术> 实验八:Web基础 1. 实践内容 1.1 Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET ...