1.什么是工厂模式
 实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式
2.工厂模式好处
 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。利用工厂模式可以降低程序的耦合性,为后期的维护修改提供了很大的便利。工厂模式对选择实现类、创建对象进行统一管理和控制。从而将调用者跟我们的实现类解耦。
3.工厂模式分类
1.简单工厂模式
        简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护。简单工厂的关系模式如下,ConcreteProduct实现AbstractProduct接口,在ConcreteProduct实现不同的产品生产,SimpleFactory根据不同的需要,调用创建不同的ConcreteProduct,FactoryClient传递参数给SimpleFactory获取需要的返回结果。

1、代码实现
先定义一个抽象的产品接口。
package com.designpattern.simplefactory;
/**
 * @description: 抽象产品
 * @author: Codegitz
 * @create: 2020-05-17 13:08
 **/
public interface AbstractProduct {
    public void product();
}
为了简单演示,这里只进行了两个实现。
package com.designpattern.simplefactory;
/**
 * @description: 产品1 ConcreteProduct1
 * @author: Codegitz
 * @create: 2020-05-17 13:08
 **/
public class ConcreteProduct1 implements AbstractProduct {
    @Override
    public void product() {
        System.out.println(" ConcreteProduct1 in production....");
    }
}
package com.designpattern.simplefactory;
/**
 * @description: 产品2 ConcreteProduct2
 * @author: Codegitz
 * @create: 2020-05-17 13:08
 **/
public class ConcreteProduct2 implements AbstractProduct {
    @Override
    public void product() {
        System.out.println(" ConcreteProduct2 in production....");
    }
}
package com.designpattern.simplefactory;
import io.netty.util.internal.StringUtil;
/**
 * @description: 简单工厂
 * @author: Codegitz
 * @create: 2020-05-17 13:10
 **/
public class SimpleFactory {
    public static AbstractProduct creatProdution(String name){
        if (StringUtil.isNullOrEmpty(name)){
            return null;
        }
        //根据传入的参数获取不同的产品
        if (name.equals("product1")){
            return new ConcreteProduct1();
        }else if (name.equals("product2")){
            return new ConcreteProduct2();
        }else {
            throw new RuntimeException("么有这个产品");
        }
    }
}
建立FactoryClient进行测试。
package com.designpattern.simplefactory;
/**
 * @description: 工厂客户端,使用简单工厂{@Link SimpleFactory}去创建产品
 * @author: Codegitz
 * @create: 2020-05-17 13:16
 **/
public class FactoryClient {
    public static void main(String[] args) {
        //创建产品
        AbstractProduct production1 = SimpleFactory.creatProdution("product1");
        AbstractProduct production2 = SimpleFactory.creatProdution("product2");
        production1.product();
        production2.product();
    }
}
运行结果如下,符合预期
 ConcreteProduct1 in production....
 ConcreteProduct2 in production....
2、简单工厂的优点/缺点
优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则
2.工厂方法模式
 工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
 工厂方法模式继承关系如图,相对于简单工厂,工厂方法模式多了一个具体实现的工厂,分担了核心工厂类的功能和职责。

为了不重复过多的代码,这里只贴出与简单工厂模式不同部分的代码。区别为两个具体工厂的实现
产品1的工厂实现ConcreteProduct1Factory
package com.designpattern.factorymethod;
/**
 * @description: ConcreteProduct1Factory 生产产品1的具体工厂
 * @author: Codegitz
 * @create: 2020-05-17 13:41
 **/
public class ConcreteProduct1Factory implements AbstractFactory {
    @Override
    public AbstractProduct createProduct() {
        //返回产品1
        return new ConcreteProduct1();
    }
}
产品2的工厂实现ConcreteProduct2Factory
package com.designpattern.factorymethod;
/**
 * @description: ConcreteProduct2Factory 生产产品2的具体工厂
 * @author: Codegitz
 * @create: 2020-05-17 13:41
 **/
public class ConcreteProduct2Factory implements AbstractFactory {
    @Override
    public AbstractProduct createProduct() {
        //返回产品2
        return new ConcreteProduct2();
    }
}
测试代码
package com.designpattern.factorymethod;
/**
 * @description: 测试工厂方法模式
 * @author: Codegitz
 * @create: 2020-05-17 13:49
 **/
public class TestClient {
    public static void main(String[] args) {
        //调用不同的工厂生产
        AbstractProduct product1 = new ConcreteProduct1Factory().createProduct();
        AbstractProduct product2 = new ConcreteProduct2Factory().createProduct();
        product1.product();
        product2.product();
    }
}
结果与简单工厂模式一致。
3.抽象工厂模式
 抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品。具体可以理解为如下图所示的结构。

类之间的继承关系图如下

抽象工厂相对复杂,代码较多,为了不重复过多代码,每个抽象的实现只贴一段实现代码。
先定义一个两个抽象产品AbstractProductA和AbstractProductB.AbstractProductB代码类似这里不进行粘贴。
package com.designpattern.abstractfactory;
/**
 * @description: 抽象产品A,需要交由具体产品{@link ConcreteProductA1}{@link ConcreteProductA2}实现
 * @author: Codegitz
 * @create: 2020-05-17 14:12
 **/
public interface AbstractProductA {
    //随便定义两个方法,让具体产品实现
    void run();
    void start();
}
使用ConcreteProductA1和ConcreteProductA2实现抽象产品接口,ConcreteProductB1和ConcreteProductB2也类似,这里不进行重复粘贴。
package com.designpattern.abstractfactory;
/**
 * @description: 产品A1实现
 * @author: Codegitz
 * @create: 2020-05-17 14:18
 **/
public class ConcreteProductA1 implements AbstractProductA {
    @Override
    public void run() {
        System.out.println("ConcreteProductA1 run....");
    }
    @Override
    public void start() {
        System.out.println("ConcreteProductA1 start...");
    }
}
建立抽象工厂AbstractFactory.
package com.designpattern.abstractfactory;
/**
 * @description: 抽象工厂,需要由具体工厂{@link ConcreteFactory1} {@link ConcreteFactory2}实现
 * @author: Codegitz
 * @create: 2020-05-17 14:12
 **/
public interface AbstractFactory {
    //定义生产产品的方法,交由具体工厂去实现
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}
定义ConcreteFactory1实现AbstractFactory,具体工厂ConcreteFactory1负责创建相应的产品。同理ConcreteFactory2代码类似,不进行重复粘贴。
package com.designpattern.abstractfactory;
/**
 * @description: 具体工厂1
 * @author: Codegitz
 * @create: 2020-05-17 14:16
 **/
public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        //生产具体产品
        return new ConcreteProductA1();
    }
    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}
附完整代码,需要自取,顺便点个star。
抽象工厂相对复杂,即对产品也进行了一层抽象,相对工厂方法多了产品的抽象,关于工厂模式之间的详细比较在此。
4.简单工厂、工厂方法、抽象工厂之小结、区别
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)
注:产品以及产品族等级关系同样见上面比较链接。
 
		