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.简单工厂、工厂方法、抽象工厂之小结、区别
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)
注:产品以及产品族等级关系同样见上面比较链接。