23种设计模式之工厂模式
参考资料
- Java设计模式:23种设计模式全面解析(超级详细)
- 韩顺平老师的Java设计模式(图解+框架源码剖析)
- 秦小波老师的《设计模式之禅》
下文如有错漏之处,敬请指正
一、简介
定义
通过类或方法创建对象
特点
- 工厂模式是一种创建型设计模式
- 实现创建者和调用者的分离
优点
- 良好的封装性,代码结构清晰,只要知道产品的类名(或约束字符串)就可以创建对象,不用知道创建对象的艰辛过程,降低模块间的耦合。
- 扩展性优秀,在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类。
- 屏蔽产品类,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。
通用类图
-
Product:抽象产品类,负责定义产品的共性
-
ConcreteProduct:具体产品类
-
Creator:抽象工厂类,负责定义工厂的共性,
-
ConcreteCreator:具体工厂类
应用场景
- JDK中Calendar的getInstance方法
- JDBC中Connection对象的获取
- SpringIOC容器创建管理Bean对象
- 反射中Class对象的newInstance方法
二、实现分类
-
静态(简单)工厂模式
-
用来生产任意产品
每个产品由统一工厂,如轮胎工厂专门生产轮胎,生产奔驰轮胎,生产宝马轮胎
-
缺点:增加新产品(特斯拉轮胎)需要修改工厂代码
-
-
工厂(方法)模式
-
用来生产固定产品
每个产品由各自的工厂负责生产,如奔驰轮胎工厂生产奔驰轮胎,宝马轮胎工厂生产宝马轮胎。
-
缺点:增加新产品(特斯拉轮胎),就必须相应增加一个工厂类(特斯拉轮胎工厂),维护时需要考虑两个对象之间的关系。
-
静态(简单)工厂模式
静态(简单)工厂模式不需要创建抽象工厂类(Creator)
静态(简单)工厂模式用于简单对象的创建
需求:每个产品由统一工厂,如轮胎工厂专门生产轮胎,生产奔驰轮胎,生产宝马轮胎。
Product:轮胎类(Tyre)
ConcreteProduct:奔驰轮胎(BenzTyre)、(宝马轮胎)BmwTyre
ConcreteCreator:轮胎工厂(TyreFactory)
Tyre:
package factory.StaticFactory;
public abstract class Tyre {
// 产品的公共方法
public void commonMethod(){
// 业务逻辑
}
// 抽象方法
abstract public void createTyre();
}
BenzTyre:
package factory.StaticFactory;
public class BenzTyre extends Tyre {
@Override
public void createTyre() {
System.out.println("生产奔驰轮胎……");
}
}
BmwTyre:
package factory.StaticFactory;
public class BmwTyre extends Tyre {
@Override
public void createTyre() {
System.out.println("生产宝马轮胎……");
}
}
TyreFactory:
只能生产已添加的产品
package factory.StaticFactory;
public class TyreFactory {
public static Tyre getInstanceByClassName(String brand){
switch (brand){
case "Benz":
return new BenzTyre();
case "BMW":
return new BmwTyre();
default:
return null;
}
}
/**
* 在这里采用了泛型(Generic)
* 通过定义泛型对getInstanceByClass的输入参数产生两层限制:
* 必须是Class类型;
* 必须是Tyre的实现类。
* 其中的"T"表示的是,只要是Tyre的子类都可以作为参数
*/
public static <T extends Tyre> T getInstanceByClass(Class<T> clazz){
Tyre tyre=null;
try{
tyre=(Tyre)Class.forName(clazz.getName()).newInstance();
}catch (Exception e){
System.out.println("没有该产品");
}
return (T)tyre;
}
}
Client:
package factory.StaticFactory;
public class Client {
public static void main(String[] args) {
Tyre benzTyre = TyreFactory.getInstanceByClassName("Benz");
benzTyre.createTyre();
Tyre bmwTyre = TyreFactory.getInstanceByClassName("BMW");
bmwTyre.createTyre();
/**
* 输出结果:
* 生产奔驰轮胎……
* 生产宝马轮胎……
*/
Tyre benzTyre0 = TyreFactory.getInstanceByClass(BenzTyre.class);
benzTyre0.createTyre();
Tyre bmwTyre0 = TyreFactory.getInstanceByClass(BmwTyre.class);
bmwTyre0.createTyre();
/**
* 输出结果:
* 生产奔驰轮胎……
* 生产宝马轮胎……
*/
}
}
工厂(方法)模式
工厂(方法)模式用于复杂对象的创建
需求:每个产品由各自的工厂负责生产,如奔驰轮胎工厂生产奔驰轮胎,宝马轮胎工厂生产宝马轮胎。
Product:轮胎类(Tyre)
ConcreteProduct:奔驰轮胎(BenzTyre)、(宝马轮胎)BmwTyre
Creator:轮胎工厂(TyreFactory)
ConcreteCreator:奔驰轮胎工厂(BenzTyreFactory)、宝马轮胎工厂(BmwTyreFactory)
Tyre:
package factory.FactoryMethod;
public abstract class Tyre {
// 产品的公共方法
public void commonMethod() {
// 业务逻辑
}
// 抽象方法
public abstract void createTyre();
}
BenzTyre:
package factory.FactoryMethod;
public class BenzTyre extends Tyre {
@Override
public void createTyre() {
System.out.println("生产奔驰轮胎……");
}
}
BmwTyre:
package factory.FactoryMethod;
public class BmwTyre extends Tyre{
@Override
public void createTyre() {
System.out.println("生产宝马轮胎……");
}
}
TyreFactory:
package factory.FactoryMethod;
public abstract class TyreFactory {
// 工厂的公共方法
public void commonMethod() {
// 业务逻辑
}
// 抽象方法
public abstract Tyre createTyre();
}
BenzTyreFactory:
package factory.FactoryMethod;
public class BenzTyreFactory extends TyreFactory {
@Override
public Tyre createTyre() {
return new BenzTyre();
}
}
BmwTyreFactory:
package factory.FactoryMethod;
public class BmwTyreFactory extends TyreFactory{
@Override
public Tyre createTyre() {
return new BmwTyre();
}
}
Client:
通过具体产品工厂获得产品
package factory.FactoryMethod;
public class Client {
public static void main(String[] args) {
Tyre benzTyre = (new BenzTyreFactory()).createTyre();
benzTyre.createTyre();
Tyre bmwTyre = (new BmwTyreFactory()).createTyre();
bmwTyre.createTyre();
/**
* 输出结果:
* 生产奔驰轮胎……
* 生产宝马轮胎……
*/
}
}
三、总结
- 工厂模式可以通过类或方法创建对象。
- 工厂模式在项目中使用得非常频繁,尤其静态(简单)工厂模式。