工厂模式根据抽象程度的不同分为三种:
- 简单工厂模式(也叫静态工厂模式)
- 工厂方法模式
- 抽象工厂模式
优点:
-
可以使代码结构清晰,有效地封装变化。
在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。 -
对调用者屏蔽具体的产品类。
如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。 -
降低耦合度。
产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。
1.简单工厂模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
角色:
- 抽象产品:IProduct
- 具体产品:ProductA、ProductB、ProductC
- 工厂:
IProduct
public interface IProduct {
}
ProductA
class ProductA implements IProduct {
}
ProductB
class ProductB implements IProduct {
}
ProductC
class ProductC implements IProduct {
}
Factory
public class Factory {
public static IProduct create(int type){
switch (type) {
case 1:
return new ProductA();
case 2:
return new ProductB();
case 3:
return new ProductC();
default:
return new ImplC();
}
}
}
Client
public class Client {
public static void main(String[] args) {
Api obj = Factory.create(2);
obj = Factory.create(3);
}
}
弊端:
对象的生成通过Factory来完成,通过不同类型来创建不同的对象,所以需要传入类型或者标记。
这种方式只需要一个工厂类,客户端使用的时候指明类型,在工厂类中进行判断后生成对象。在维护的时候不方便,需要修改工厂类容易造成代码冗余,同时也没有做到开闭原则。在对简单工厂的优化后进入工厂方法模式。
2.工厂方法模式
定义:
工厂方法模式是在简单工厂模式的基础上进行抽取封装和优化之后的产物。
简单工厂模式.png角色:
- 抽象产品:IProduct
- 具体产品:Product
- 抽象工厂:IFactory
- 具体工厂:Factory
IProduct
interface IProduct {
public void productMethod();
}
Product
class Product implements IProduct {
public void productMethod() {
System.out.println("产品");
}
}
IFactory
interface IFactory {
public IProduct createProduct();
}
Factory
class Factory implements IFactory {
public IProduct createProduct() {
return new Product();
}
}
public class Client {
public static void main(String[] args) {
IFactory factory = new Factory();
IProduct prodect = factory.createProduct();
prodect.productMethod();
}
}
3.抽象工厂模式
抽象工厂模式是工厂方法模式的升级版本,这里需要注意他们之间的区别,往往容易混淆。
在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。我们依然拿生产汽车的例子来说明他们之间的区别。
抽象工厂的例子.png在上面的类图中,两厢车和三厢车称为两个不同的等级结构;而2.0排量车和2.4排量车则称为两个不同的产品族。再具体一点,2.0排量两厢车和2.4排量两厢车属于同一个等级结构,2.0排量三厢车和2.4排量三厢车属于另一个等级结构;而2.0排量两厢车和2.0排量三厢车属于同一个产品族,2.4排量两厢车和2.4排量三厢车属于另一个产品族。
明白了等级结构和产品族的概念,就理解工厂方法模式和抽象工厂模式的区别了,如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。在本例中,如果一个工厂模式提供2.0排量两厢车和2.4排量两厢车,那么他属于工厂方法模式;如果一个工厂模式是提供2.4排量两厢车和2.4排量三厢车两个产品,那么这个工厂模式就是抽象工厂模式,因为他提供的产品是分属两个不同的等级结构。当然,如果一个工厂提供全部四种车型的产品,因为产品分属两个等级结构,他当然也属于抽象工厂模式了。
代码
产品接口1
interface IProduct1 {
public void show();
}
产品接口2
interface IProduct2 {
public void show();
}
具体产品1
class Product1 implements IProduct1 {
public void show() {
System.out.println("这是1型产品");
}
}
具体产品2
class Product2 implements IProduct2 {
public void show() {
System.out.println("这是2型产品");
}
}
工厂接口
interface IFactory {
public IProduct1 createProduct1();
public IProduct2 createProduct2();
}
具体工厂
class Factory implements IFactory{
public IProduct1 createProduct1() {
return new Product1();
}
public IProduct2 createProduct2() {
return new Product2();
}
}
客户端
public class Client {
public static void main(String[] args){
IFactory factory = new Factory();
factory.createProduct1().show();
factory.createProduct2().show();
}
}
抽象工厂模式的优点
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
抽象工厂模式的缺点
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
适用场景
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。
4.总结
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。
网友评论