在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。也就是通过工厂方法来代替new操作的一种模式。按实际业务场景划分,工厂模式有 3 种不同的实现方式,分别是简单工厂模式、工厂方法模式和抽象工厂模式。
1、简单工厂模式
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。 简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式,简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类 ,这增加了系统的复杂度,违背了“开闭原则”。因此,对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
- UML图
简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
具体产品(Product01/Product02):是简单工厂模式的创建目标。
- 代码
package com.lzq.FactoryPattern;
public class Factory_Simple {
public static void main(String[] args) {
}
//抽象产品
public interface Product {
void show();
}
//具体产品:Product01
static class Product01 implements Product {
public void show() {
System.out.println("生产产品1");
}
}
//具体产品:Product02
static class Product02 implements Product {
public void show() {
System.out.println("生产产品2");
}
}
final class Const {
static final int PRODUCT_A = 0;
static final int PRODUCT_B = 1;
static final int PRODUCT_C = 2;
}
public static class SimpleFactory {
public static Product makeProduct(int kind) {
switch (kind) {
case Const.PRODUCT_A:
return new Product01();
case Const.PRODUCT_B:
return new Product02();
}
return null;
}
}
}
- 缺点
- 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
- 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度。
- 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
- 总结
简单工厂类就是通过一个工厂类通过传入的不同参数来创建产品类,每增加一个产品类就需要修改工厂类。
2、工厂方法模式
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
- UML
抽象产品(Product):定义工厂方法所创建的对象的接口,也就是实际需要使用的对象的接口。
具体产品(Product01/02):具体的Product接口的实现对象。
抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
具体工厂(Factory01/02):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 代码
package com.lzq.FactoryPattern;
public class Factory_method {
//抽象产品:提供了产品的接口
interface Product {
public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class Product01 implements Product {
public void show() {
System.out.println("生产产品01");
}
}
//具体产品2:实现抽象产品中的抽象方法
class Product02 implements Product {
public void show() {
System.out.println("生产产品02");
}
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory {
public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class Factory01 implements AbstractFactory {
public Product newProduct() {
return new Product01();
}
}
//具体工厂2:实现了厂品的生成方法
class Factory02 implements AbstractFactory {
public Product newProduct() {
return new Product02();
}
}
public static void main(String[] args){
Factory_method factory_method = new Factory_method();
AbstractFactory factory01 = factory_method.new Factory01();
factory01.newProduct().show();
AbstractFactory factory02 = factory_method.new Factory02();
factory02.newProduct().show();
}
}
- 总结
定义一个工厂接口,让实现工厂接口的类去实例化产品类,一个产品类对应着一个工厂类。工厂方法模式对核心工厂类做了进一步的抽象,他使用了面向对象的多态性,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
3、抽象工厂模式
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
- UML:
- 抽象工厂(AbstractFactory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
- 抽象产品(AbstractProduct01/02):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体工厂(ConcreteFactory_A/_B):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 具体产品(ConcreteProduct_A01/02 ConcreteProduct_B01/02):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
- 代码:
package com.lzq.FactoryPattern;
public class Factory_Abstract {
//抽象产品01
interface AbstractPorduct01{
void show();
}
//抽象产品02
interface AbstractProduct02{
void show();
}
//A类具体产品01
class ConcreteprodutA_01 implements AbstractPorduct01{
@Override
public void show() {
System.out.println("======生产A类具体产品01");
}
}
//A类具体产品02
class ConcreteProductA_02 implements AbstractProduct02{
@Override
public void show() {
System.out.println("======生产A类具体产品02");
}
}
//B类具体产品01
class ConcreteProductB_01 implements AbstractPorduct01{
@Override
public void show() {
System.out.println("=======生产B类具体产品01");
}
}
//B类具体产品02
class ConcreteProductB_02 implements AbstractProduct02{
@Override
public void show() {
System.out.println("=======生产B类产具体产品02");
}
}
//抽象工厂
interface AbstractFactory{
public AbstractPorduct01 CreConProduct01();
public AbstractProduct02 CreConProduct02();
}
//具体工厂A,生产A类产品01/02
class ConcreteFactory_A implements AbstractFactory{
@Override
public AbstractPorduct01 CreConProduct01() {
return new ConcreteprodutA_01();
}
@Override
public AbstractProduct02 CreConProduct02() {
return new ConcreteProductA_02();
}
}
//具体工厂B,生产B类产品01/02
class ConcreteFactory_B implements AbstractFactory{
@Override
public AbstractPorduct01 CreConProduct01() {
return new ConcreteProductB_01();
}
@Override
public AbstractProduct02 CreConProduct02() {
return new ConcreteProductB_02();
}
}
public static void main(String[] args){
Factory_Abstract factory_abstract = new Factory_Abstract();
AbstractFactory FactoryA = factory_abstract.new ConcreteFactory_A();
FactoryA.CreConProduct01().show();
FactoryA.CreConProduct02().show();
AbstractFactory FactoryB = factory_abstract.new ConcreteFactory_B();
FactoryB.CreConProduct01().show();
FactoryB.CreConProduct02().show();
}
}
总结:抽象工厂模式就是工厂方法模式的升级版:工厂方法模式一个工厂只生产一种产品,抽象工厂模式一个工厂生产一类产品。