目录
一、什么是简单工厂模式
简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。为客户端提供一个创建对象实例的功能,通过专门定义一个类来负责创建其他类的实例,而无须关心其具体实现,被创建实例的类可以是接口,抽象类,或者具体类,通常都具有共同的父类。
简单工厂模式不属于标准的设计模式。
二、模式中包含的角色及其职责
1.工厂(Factory)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
2.抽象(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
3.具体产品(Concrete Product)角色
简单工厂模式所创建的具体实例对象
4.客户端(Client)角色
通过Factory去获取Product
三、代码示例
package demo;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:53
* @Description: 接口,可通过简单工厂创建
*/
public interface Api {
/**
* 示例,具体功能方法
* @param msg
*/
void oper(String msg);
}
package demo;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:53
* @Description:
*/
public class ImplA implements Api{
@Override
public void oper(String msg) {
//实现接口功能
System.out.println("ImplA " + msg);
}
}
package demo;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:54
* @Description:
*/
public class ImplB implements Api{
@Override
public void oper(String msg) {
System.out.println("ImplB " + msg);
}
}
package demo;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:54
* @Description: 工厂 用来创建Api对象
*/
public class Factory {
/**
* 具体创建Api的方法
* @param type
* @return
*/
public static Api createApi(int type){
/**
* 应该根据条件去选择究竟创建哪一个具体的实现对象
* 这些条件可以从外部传入,也可以从其他途径获取。
* 若只有一个实现,可以不用条件选择
*/
//示意使用条件
Api api = null;
if(type == 1){
api = new ImplA();
}else if(type == 2){
api = new ImplB();
}
return api;
}
}
package demo;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:53
* @Description:
*/
public class Client {
public static void main(String[] args) {
Api api = Factory.createApi(1);
api.oper("Simple Factory");
}
}
四、理解简单工厂
认识简单工厂
简单工厂功能
可以用来创建接口,抽象类或普通类的实例
静态工厂
通常把简单工厂类实现成一个工具类,直接使用静态方法就可以了,也就是说简单工厂的方法通常是静态的,所以也被称为静态工厂
万能工厂
一个简单工厂理论上可以用来构造任何对象
简单工厂创建对象的范围
建议控制在一个独立的组件级别或一个模块级别
命名建议
类名建议为“模块名称+Factory”
方法名建议为“get+接口名”或“create+接口名”
简单工厂中方法的写法
简单工厂方法的内部主要实现的功能是“选择合适的实现类”来创建实例对象
如何选择?选择的参数从哪来?
1.参数来源于客户端
2.参数来源于配置文件
3.参数来源于系统自身,如运行时的某个值
注意:如果是从客户端在调用工厂的时候,传入选择的参数,这就说明客户端必须知道每个参数的含义,也需要理解每个参数对应的功能处理。这就要求在一定程度上,向客户暴露一定的内部实现细节。
可配置的简单工厂
使用后反射加上配置文件,来实现添加新的实现类过后,无需修改代码,就能把新实现类加入到应用中。
factory.properties
ImplClass = demo2.ImplA
package demo2;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:54
* @Description: 工厂 用来创建Api对象
*/
public class Factory {
/**
* 具体创建Api的方法
* 根据配置文件的参数来创建接口
* @param type
* @return
*/
public static Api createApi(){
/**
* 读取配置文件来获取需要创建的实例类
*/
Properties properties = new Properties();
InputStream inputStream = null;
inputStream = Factory.class.getResourceAsStream("factory.properties");
try {
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 利用反射去创建
*/
Api api = null;
try {
api = (Api) Class.forName(properties.getProperty("ImplClass")).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return api;
}
}
package demo2;
/**
* @Author: Zhang
* @Date: 2019/11/13 13:53
* @Description:
*/
public class Client {
public static void main(String[] args) {
Api api = Factory.createApi();
api.oper("Simple Factory");
}
}
其他代码不变。选择的过程在配置文件里实现,配置的是什么,就创建什么。
简单工厂模式的优缺点
封装。在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
解耦。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的,有利于整个软件体系结构的优化。
简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。
另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。
增加客户端的复杂度,主要体现在选择参数的传递上。
五、思考简单工厂模式
本质
选择实现
何时选用
1.想完全封装隔离具体实现,让外部只能通过接口来操作封装体,可以选用简单工厂,让客户端通过工厂来获取相应接口,而无需关心具体实现
2.想把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个工厂可以创建很多不相关的对象,可以把对外创建对象的功能集中到一个简单工厂里来,从而实现集中管理和控制