工厂模式是我们日常开发中经常使用的设计模式。当我们需要创建一些比较负责的对象的时候,为了将对象的初始化部分进行隔离,可以使用工厂模式来设计我们的代码。
一般来说工程模式可以分为一下3种方式:简单工厂模式、工厂方法模式、抽象工厂模式。
简单工厂模式
简单工厂方法模式又叫做静态工厂方法模式,它也是最简单的一种,所有的实例对象都是由一个工厂类来创建。简单工厂模式一般来说需要具备3种元素:
抽象产品类或者接口
具体的产品类,继承或者实现抽象产品
-
工厂类,由它来创建上面的这些具体的产品对象
public abstract class ProductBase {
public abstract void action();
}public class ProductA extends ProductBase{
@Override
public void action() {
System.out.println("I'm product A");
}
}public class ProductB extends ProductBase {
@Override
public void action() {
System.out.println("I'm product B");
}
}public class SimpleProductFactory {
public static ProductBase createProduct(String type) { switch (type){ case "A": return new ProductA(); case "B": return new ProductB(); default: break; } return null; }
}
简单工厂方法确实挺简单的,但是它却有个问题,比如我们的功能需求有变动,需要再增加一个或者多个产品的话,那么我们的工厂类就需要重新进行修改了,需要再增加一个或者多个case判断,这就不符合我们的开闭原则,对修改封闭。
为了解决这个问题,引入了我们的工厂方法模式。
工厂方法模式
工厂方法的核心点是将简单工厂模式中工厂类的创建方法将其抽象出来了。如果需要创建哪个产品就需要增加一个具体的工厂类来实现这个抽象工厂。如图所示:
我们的产品类不用修改,将工厂类修改为如下形式:
public abstract class ProductFactoryBase {
public abstract ProductBase createProduct();
}
public class ProductFactoryA extends ProductFactoryBase{
@Override
public ProductBase createProduct() {
return new ProductA();
}
}
public class ProductFactoryB extends ProductFactoryBase{
@Override
public ProductBase createProduct() {
return new ProductB();
}
}
假如我们的需求变了,需要增加一个产品,那么我们的产品C继承ProductBase这个是肯定的,我们的工厂类就只需要继承FactoryBase来创建ProductC就可以,它并没有修改原来的工厂类,这样就符合了我们的开闭原则-修改封闭,扩展开放。
我们可以看到,工厂方法模式有一个明显的问题就是如果我们的产品过多的话,就需要针对每个产品引入工厂类,这样就势必让我们的类结构更加的复杂了。所以在实际开发中是否需要使用需要自己权衡利弊。
抽象工厂模式
抽象工厂模式和工厂方法模式类似,它提供了创建多个产品的接口,由具体的工厂来创建各个产品对象。
创建抽象工厂类:
public abstract class ProductFactoryBase {
public abstract ProductBaseA createProductA();
public abstract ProductBaseB createProductB();
}
创建工厂类:
public class ProductFactory1 extends ProductFactoryBase{
@Override
public ProductBaseA createProductA() {
return new ProductA1();
}
@Override
public ProductBaseB createProductB() {
return new ProductB1();
}
}
public class ProductFactory2 extends ProductFactoryBase{
@Override
public ProductBaseA createProductA() {
return new ProductA2();
}
@Override
public ProductBaseB createProductB() {
return new ProductB2();
}
}
创建抽象产品类:
public abstract class ProductBaseA {
public abstract void actionA();
}
public abstract class ProductBaseB {
public abstract void actionB();
}
创建产品类:
public class ProductA1 extends ProductBaseA {
@Override
public void actionA() {
System.out.println("I'm product A1");
}
}
public class ProductA2 extends ProductBaseA {
@Override
public void actionA() {
System.out.println("I'm product A2");
}
}
public class ProductB1 extends ProductBaseB {
@Override
public void actionB() {
System.out.println("I'm productB1");
}
}
public class ProductB2 extends ProductBaseB {
@Override
public void actionB() {
System.out.println("I'm productB2");
}
}
可以看到抽象工厂模式和工厂方法模式类似,它们的缺点也类似,都有大量类的类在里面,当产品过多的时候回造成类的结构比较复杂。同时它还有另一个问题就是如果需要增加一个或者多个其他类型的产品的时候,这个时候我们就需要修改我们的抽象工厂类和所有的具体工厂类,这也是违反了我们的开闭原则,所以在实际中抽象工厂模式用的也是比较少的。
在实际开发中如何使用这3种工厂方式需要根据自己的业务功能去衡量,工厂模式目的也是为了隔离对象的创建,将与初始化对象相关的逻辑剥离出去,我们也看到工厂模式是有它的利弊在里面的,不能为了模式而使用模式,否则会适得其反。