简单工厂模式
简单工厂模式是类的创建模式,又称静态工厂方法模式。简单工厂模式的实质是由一个工厂类根据具体的参数,动态创建具体的实现类(这些实现类都继承自一个父类或接口)的实例。
为什么要使用简单工厂模式
解耦合:A对象调用B对象时,通过new创建一个B对象,当要用C对象取代B对象时,程序不得不重写A中的代码,如果A中new了B有100次,那么需修改100次,这就是因为代码耦合度高导致的。通过一个工厂类来决定所需要的是B类还是C类,让A类与该工厂类耦合就能解决。
简单工厂模式示例
1 interface Operation {
2 //计算
3 double arithmetic(double a, double b);
4 }
四个子类:加减乘除
1 //加法
2 class Append implements Operation {
3
4 @Override
5 public double arithmetic(double a, double b) {
6 return a + b;
7 }
8
9 }
10
11 //减法
12 class Subtraction implements Operation {
13
14 @Override
15 public double arithmetic(double a, double b) {
16 return a - b;
17 }
18
19 }
20
21 //乘法
22 class Multiplication implements Operation {
23
24 @Override
25 public double arithmetic(double a, double b) {
26 return a * b;
27 }
28
29 }
30
31 //除法
32 class Division implements Operation {
33
34 @Override
35 public double arithmetic(double a, double b) {
36 double result = 0;
37 try {
38 result = a / b;
39 } catch (Exception e) {
40 System.out.println("除数不能为0");
41 }
42 return result;
43 }
44
45 }
工厂类:决定具体的操作
1 //对象工厂
2 class OperationFactory {
3
4 public Operation objectFactory(String s) {
5 switch (s) {
6 case "+":
7 return new Append();
8 case "-":
9 return new Subtraction();
10 case "*":
11 return new Multiplication();
12 case "/":
13 return new Division();
14 default:
15 return null;
16 }
17 }
测试:
1 public static void main(String[] args) {
2 Scanner in = new Scanner(System.in);
3 System.out.println("请输入第一个数:");
4 String s1 = in.nextLine();
5 double numA = Double.valueOf(s1);
6 System.out.println("请输入运算符号:(+,-,*,/)");
7 String symbol = in.nextLine();
8 System.out.println("请输入第二个数:");
9 double numB = in.nextDouble();
10
11 OperationFactory of = new OperationFactory();
12 Operation op = of.objectFactory(symbol);
13 double result = op.arithmetic(numA, numB);
14 System.out.println(result);
15 }
这样用户不用自己去创建操作对象,只需拿自己需要的对象就可以了,这样用户和操作对象之间的耦合度就降低了,且代码模块的职责更明确了,有生产对象的模块也有消费对象的模块。
改进
上面的代码也存在问题,每当增加一个运算操作时,OperationFactory对象工厂就要增加一个条件,很不方便,可以通过反射来改进:
1 public Operation objectFactory2(String s) throws Exception {
2 Class<?> c = Class.forName(s);
3 return (Operation) c.newInstance();
4 }
这样有一个缺点就是类路径的问题。可以创建一个接口专门创捷不同操作的类路径的常量,也可以将类路径的常量写入properties文件,或xml文件中,这样当想再增加一个操作时,只需修改这个文件。
最后说一点:简单工厂模式或者说工厂模式关注的点不在于工厂中是如何生产出需要的类的,而在于将创建与消费分离。
工厂模式的优缺点
优点:
1. 通过工厂类,外界不需要直接创建具体的对象,只需要负责消费(使用),更不需要关心内部是如何创建对象。
2. 优化了体系结构,明确了各个模块的功能和职责。
缺点:
1. 改进前的简单工厂模式,新增加一个功能或操作,就要修改工厂类
2. 改进前的简单工厂模式,实例的创建逻辑全放在工厂类中,违反了高内聚责任分配原则,且每增加一个操作,就要多一个条件判断,对系统的维护和扩展不利
3. 改进后的简单工厂模式,由于使用反射,效率会比之前低
工厂方法模式
简单说下,工厂方法模式是对简单工厂模式的进一步抽象的结果。工厂方法模式将工厂给抽象化,将具体的创建工作交给不同的工厂子类去实现。这个类变成了一个抽象工厂类,仅仅给出具体工厂子类必须实现的接口。
这一步的改进使得当需要增加一个新的功能或操作,只需增加该类和一个继承了抽象工厂类的具体实现工厂类,不需要修改其他类的代码。克服了改进之前简单工厂模式违背开闭原则的缺点,又保持了封装对象创建过程的优点。但是每增加一个产品或功能,都要增加一个对应的工厂类,增加了额外的开发量。