模式说明

当客户端需要根据某个变量的不同值来声明不同的对象时,可以使用简单工厂模式。该模式设置了一个生产产品(前述的对象)的工厂类,此工厂类通过静态方法(所以称为静态工厂),传入变量参数,方法体内有选择分支(if-elseswitch-case),根据参数返回具体的产品。举个例子,天气是变量,客户端根据天气的不同情况,令服装工厂生产不同的服装,下雨生产雨衣,低温天气生产羽绒服,高温天气生产泳衣等等。在这个例子中服装工厂就是静态工厂,不同的雨衣是不同的具体产品。天气情况就是静态方法的参数。让不同的产品都继承同一个抽象产品类,那么这个抽象产品类,具体的产品类和静态工厂类就形成了简单工厂的完整结构。
注:简单工厂模式不在GoF的23种设计模式之列。

当产品类有增删改时,需要在静态工厂类中修改选择分支,因此简单工厂模式不满足开闭原则。这个问题要留到工厂方法模式解决。

本示例以四则运算为例,演示客户端如何通过运算符从运算工厂中获取相应的运算产品,然后执行该产品的产品方法(执行运算)返回结果。

结构

静态工厂类
维护一个静态方法,根据参数返回具体产品类的实例(返回类型是抽象产品类型)。
抽象产品类
定义产品字段和方法(操作数a,b和运算方法result())
具体产品类
继承抽象产品类,实现具体运算方法

代码演示

  1. package com.yukiyama.pattern.creation;
  2. /**
  3. * 简单工厂模式(静态工厂模式)
  4. */
  5. public class StaticFactoryDemo {
  6. public static void main(String[] args) {
  7. // 通过静态工厂类静态方法返回一个具体产品。
  8. Operation oper = OperationFactory.operate("*");
  9. // 执行该产品的方法。输出“12”
  10. System.out.println(oper.result(3, 4));
  11. }
  12. }
  13. /**
  14. * 静态工厂类
  15. * 通过一个类静态方法,根据输入返回相应的工厂类。内部通常为if-else或
  16. * switch-case。
  17. */
  18. class OperationFactory{
  19. public static Operation operate(String sign) {
  20. Operation oper = null;
  21. switch (sign) {
  22. case "+":
  23. oper = new OperationAdd();
  24. break;
  25. case "-":
  26. oper = new OperationSub();
  27. break;
  28. case "*":
  29. oper = new OperationMul();
  30. break;
  31. case "/":
  32. oper = new OperationDiv();
  33. break;
  34. default:
  35. System.out.println("不支持此运算。");
  36. }
  37. return oper;
  38. }
  39. }
  40. /**
  41. * 抽象产品类
  42. * 定义产品的抽象方法。
  43. * 下例以四则运算为产品,内有对两个int数的运算方法。
  44. */
  45. abstract class Operation{
  46. public abstract int result(int a, int b);
  47. }
  48. /**
  49. * 具体产品类
  50. * 继承抽象产品类,实现抽象方法。
  51. * 下例为加法产品。
  52. */
  53. class OperationAdd extends Operation{
  54. @Override
  55. public int result(int a, int b) {
  56. return a + b;
  57. }
  58. }
  59. /**
  60. * 具体产品类,减法
  61. */
  62. class OperationSub extends Operation{
  63. @Override
  64. public int result(int a, int b) {
  65. return a - b;
  66. }
  67. }
  68. /**
  69. * 具体产品类,乘法
  70. */
  71. class OperationMul extends Operation{
  72. @Override
  73. public int result(int a, int b) {
  74. return a * b;
  75. }
  76. }
  77. /**
  78. * 具体产品类,除法
  79. */
  80. class OperationDiv extends Operation{
  81. @Override
  82. public int result(int a, int b) {
  83. if(b == 0) {
  84. System.err.println("除数不能为0.");
  85. throw new IllegalArgumentException();
  86. }
  87. return a / b;
  88. }
  89. }