一、模式定义
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式(同属于创建型模式的还有工厂方法模式,抽象工厂模式,单例模式,建造者模式)。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
二、UML图结构:
简单工厂模式
我们先来看简单工厂模式的UML图(UML图大家可以去简单学习下):
上图角色主要分为三部分:
简单工厂类:这是核心内容,它是用来创建所有实现类的内部处理逻辑。该类被调用,根据所传递的参数来决定实例化对应的类。
抽象类(运算类):简单工厂模式所创建所有对象的父类。
实现类(加减乘除类):所创建的具体实例对象,当然这些具体的类都是继承上面的抽象类。
三、实例分析:
通过计算器小例子来简单入门了解下简单工厂模式。这里计算器讲解仅实现加减乘除功能,通过面向对象的思想来设计,引入简单工厂模式。
先看下抽象类和实现类简单代码:
public abstract class Operation { //抽象类,运算类 public int numberA, numberB; //运算的两个数据 abstract int getResult(); //抽象方法,返回运算结果 } class AddOperation extends Operation { //加法类 @Override int getResult() { return numberA + numberB; } } class SubOperation extends Operation { //减法类 @Override int getResult() { return numberA - numberB; } } class MulOperation extends Operation { //乘法类 @Override int getResult() { return numberA * numberB; } } class DivOperation extends Operation { //除法类 @Override int getResult() { if (numberB == 0) { throw new ArithmeticException("除数不能为0"); } return numberA / numberB; } }
那么下面是工厂类代码:
public class OperationFactory { //运算符加工厂 public static Operation createOperate(char operate) { //生产运算类 Operation op = null; switch (operate) { case '+': op = new AddOperation(); break; case '-': op = new SubOperation(); break; case '*': op = new MulOperation(); break; case '/': op = new DivOperation(); break; } return op; } }
测试类:
public class Calculator { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("输入运算符:"); char operation = scanner.next().charAt(0); Operation op = OperationFactory.createOperate(operation); //通过工厂生产一个运算类 System.out.print("输入第一个数字:"); op.numberA = scanner.nextInt(); System.out.print("输入第二个数字:"); op.numberB = scanner.nextInt(); try { System.out.print("结果:" + op.getResult()); //输出运算结果 } catch (ArithmeticException e) { System.out.print(e.getMessage()); } } }
一个简单的工厂模式就完成了。实现了代码的逻辑和业务分离。并且对外还隐藏了创建实例的具体方式。同时还具有良好的扩展性,就算此时需要再添加另外一种运算方式,那么只需要添加一个具体的实现类,并在工厂中添加对应的分支即可。
四、优点:
(1)、工厂类通过逻辑判断,决定什么时候创建哪一种实现类,避免外部直接创建实例的责任。
(2)、外部不需要了解所创建实例具体类,只需要知道传递对应的参数即可,对于复杂的类,可以减轻使用者的记忆。
(3)、就算需要扩展其他的实例,也不需要修改外部代码,只需要添加对应的实力类并修改工厂类。
五、缺点:
(1)、由于所有的实力类都是工厂类创建,那么如果该类出现问题不能正常工作,那么整个系统都会受到影响。
(2)、不断的增加实例类的个数,那么就会增加系统的复杂度和理解难度。
(3)、扩展困难,每次添加新实例就需要修改工厂类,可能会造成工厂逻辑复杂,不利于维护。
六、使用场景:
在以下情况下可以使用简单工厂模式:
(1)、工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
(2)、客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
七、模式JDK使用:
JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。
public final static DateFormat getDateInstance(); public final static DateFormat getDateInstance(int style); public final static DateFormat getDateInstance(int style,Locale locale);