设计模式被分成了三种类型,这次来说一下创建型中的工厂家族(简单工厂方法,工厂方法模式,抽象工厂)。通过了解,三者之间的比较来加深对工厂家族的了解。
简单工厂:
工厂类中有必要的逻辑判断,根据客户端的选择可以动态的实例化相关类.去除了与具体产品的依赖。
例:
在上述计算器的例子结构图中,如果我们要新加一个功能,不仅要增加预算类的子类,且还要修改运算类工厂,增加switch的case分之条件,这也就违背了开放封闭原则。
所谓的开放封闭原则:就是(软件实体类,模块,函数等)对扩展开放,修改封闭。
缺点:不符合开闭原则
工厂方法:
定义一个用于创建对象的接口,让子类决定实例化哪个类.使得一个类的实例化延迟到其子类。
例:
上图是计算器的工厂方法结构图,当需要增加新的功能的时候,只需要相应增加功能的运算类和工厂类,而不需要去修改原有的工厂类。
缺点:增加一个类,需要增加额外的开发量
优点:只有扩展变化,没有修改变化。克服了开闭原则。
简单工厂VS工厂方法:
工厂方法把简单工厂内部逻辑判断移到了客户端代码来进行.之前增加功能需要修改原有工厂类,现在只需修改客户端。
两者都是集中封装了对象的创建,使得更换对象不需要做大的改动就可实现,降低了耦合性。
抽象工厂:
提供创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。
结构图:
缺点:若要增加新功能,就要增加三个类,还要修改原有类。
优点:符合开放封闭,依赖倒转原则。
易于交换产品系列;具体的创建实例过程和客户端分离,客户端是通过抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
每个模式都有自己的优缺点,如何解决所用模式的缺点呢,这里提到一个反射技术:
格式:Assembly.Load("程序集名称").createInstance("命名空间.类名称")
对于反射个人不是很理解,这里借用查到的资料来解释一下反射。 所谓反射就是根据编程语言提供的反射类,直接将字符串转化为类或方法,然后再进行调用。这样一来,在抽象工厂模式中,程序员在客户端代码中可以不知道具体的类名,通过反射来将输入或者获取到的字符串转化为抽象工厂模式中的工厂类,再调用同名方法实例化产品类,这样一来就可以完全避免使用逻辑判断了。
使用反射可以弥补抽象工厂的不足。
工厂方法VS抽象工厂:
抽象工厂模式改变了抽象工厂接口的结构。在工厂方法模式中,工厂类的方法只能实例化一种产品类;
但是在抽象工厂模式中,抽象工厂接口包含了多个抽象方法,这些方法可以实例化不同的产品类。
《设计模式》工厂家族