工厂方法模式(Factory Pattern) 是一种创建型设计模式 , 它是Java中最常用的设计模式之一 .
1 . 工厂方法模式的定义
定义一个创建对象的接口 , 让子类决定实例化哪一个类 . 工厂方法模式使一个类的实例化延迟到子类
2 . 工厂方法模式的特点
将"类实例化的操作"和"使用对象的操作"分开 , 让使用者不用知道具体参数就可以实例化出所需要的"产品"类 , 从而避免了在代码中显式指定 , 实现了解耦 .
3 . 工厂方法模式的实现思路
- 创建抽象产品接口 , 定义具体产品实例的方法
- 创建具体产品类(实现抽象产品接口) , 定义生产的具体产品
- 创建抽象工厂接口 , 定义具体工厂的通用接口
- 创建具体工厂类(实现抽象工厂接口) , 定义创建具体产品实例的方法
- 外界通过调用工厂类的方法 , 从而创建不同产品类的实例
4 . 工厂方法模式的应用场景
- 当一个类不需要知道它所需要的对象类别时
- 无序关注对象的内部实现时
5 . 代码实现
1 . 简单工厂模式(工厂模式的变种很多 , 简单工厂模式就是工厂模式家族中最简单实用的一种模式) , 又叫做静态工厂方法模式(Static Factory Method) , 简单工厂模式是由一个工厂对象创建某一产品的实例 , 主要由三部分组成
- 工厂类角色 : 该模式的核心 , 用来创建产品 , 包含创建产品的相关逻辑和判断
- 抽象产品角色 : 指具体产品继承的父类或者实现的接口
- 具体产品角色 : 工厂类所创建的对象就是该角色的实例
/** 抽象产品接口 - 汽车 */
public interface ICar {
void getCar();
}
/** 具体产品类 : 跑车 */
public class SportCar implements ICar{
@Override
public void getCar() {
System.out.println("得到一辆跑车 . ");
}
}
/** 具体产品类 : 越野车 */
class JeepCar implements ICar{
@Override
public void getCar() {
System.out.println("得到一辆越野车 . ");
}
}
/** 具体产品类 : 小货车 */
class BuggyCar implements ICar{
@Override
public void getCar() {
System.out.println("得到一辆小货车 . ");
}
}
/** 简单工厂核心类 : */
public class SimpleFactory {
public static final int CAR_TYPE_SPORT = 1;
public static final int CAR_TYPE_JEEP= 2;
public static final int CAR_TYPE_BUGGY = 3;
public static ICar getCar(int carType){
if(carType == CAR_TYPE_SPORT){
return new SportCar();
}else if(carType == CAR_TYPE_JEEP){
return new JeepCar();
}else if(carType == CAR_TYPE_BUGGY){
return new BuggyCar();
}else{
throw new RuntimeException("啥车都没找到");
}
}
}
/** 调用工厂方法 */
public class SimpleFactoryDemo {
public static void main(String[] args) {
System.out.println("来到汽车工厂 , 准备取车 : ");
try {
ICar car =SimpleFactory.getCar(SimpleFactory.CAR_TYPE_SPORT);
car.getCar();
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
调用者不再关注实例化什么对象 , 只需要将需求告诉工厂类 , 工厂类就会实例化相应的类 , 调用者不需要知道生产的细节就可以使用产品
2 . 综上述代码来看 , 不难发现简单工厂模式存在一系列问题 :
- 工厂类集中了所有实例的创建逻辑 , 一旦这个工厂不能正常工作 , 整个系统都会受到影响 .
- 违背"开放-关闭"原则 , 一旦添加新产品就不得不修改工厂类的逻辑 , 造成工厂类过于臃肿 .
- 简单工厂模式由于使用了静态工厂方法 , 静态方法不能被继承和重写 , 会造成工厂角色无法形成基于继承的等级结构 .
为了解决以上问题 , 我们又使用了新的工厂方法模式 . 工厂方法模式相对简单工厂模式多了一个角色
- 抽象工厂角色 : 与生产过程无关 , 任何在模式中创建的工厂类必须实现这个接口
抽象产品接口和产品实例类与之前一样 , 其他类代码如下
/** 抽象工厂接口 */
public interface IFactoryMethod{
ICar createCar();
}
/** 工厂实现类 */
public class SportFactory implements IFactoryMethod{
@Override
public ICar createCar() {
return new SportCar();
}
}
class JeepFactory implements IFactoryMethod{
@Override
public ICar createCar() {
return new JeepCar();
}
}
class BuggyFactory implements IFactoryMethod{
@Override
public ICar createCar() {
return new BuggyCar();
}
}
/** 调用工厂方法 */
public class FactoryMethodDemo {
public static void main(String[] args) {
System.out.println("来到汽车工厂 , 准备取车 : ");
IFactoryMethod factory1 = new SportFactory();//A工厂
ICar car1 = factory1.createCar();
System.out.print("A取车 : ");
car1.getCar();
IFactoryMethod factory2 = new JeepFactory();//B工厂
ICar car2 = factory2.createCar();
System.out.print("B取车 : ");
car1.getCar();
}
}
6 . 总结
- 单一职责
- 开闭原则
- 调用者无需关心实现