前言
在面向对象编程中,产生一个对象实例最常用的方法是使用new关键字来创建,但这样耦合度太高,如果创建此对象时,需要一些其他的操作,这些代码(创建对象和一些其他的操作)如果没有封装起来给客户端使用,客户端大量使用这些代码,一旦这些重复的操作需要更改,那么带来的工作量将是巨大的,也不利于扩展。所以我们建立一个工厂类来创建对象,让客户端只关注得到工厂生产的对象,而将生产对象的一系列操作封装起来,方便日后对生产对象的代码进行扩展和维护。
分类
工厂模式可以分为三类:
1)简单工厂模式
2)工厂方法模式
3)抽象工厂模式
简单工厂模式
定义:一个工厂类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类。
简单工厂模式只需要一个工厂类。简答工厂模式:又被称为静态工厂模式,工厂类为静态类或者包含静态方法。不属于23种GOF设计模式。实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品实例。
结构图:
Client:客户端
Factory:工厂类,提供一个工厂类用于创建各种产品。在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入参数的不同创建不同的具体产品对象。
Product:抽象产品类。
Concrete:具体产品类。
简单工厂模式的优点
工厂类中包含了必要的逻辑判断,根据客户端的选择动态实例化相关的类,对于客户端来说,去除了具体的产品依赖。
简单工厂模式的缺点
工厂类集中了所有产品的创建逻辑,职责过重。一旦需要添加新的ConcreteProduct,则需要修改Factory逻辑,这样违反了开放-关闭原则。
实例:
实现一个计算器程序,要求输入两个数和运算符号,得到结果。
思路:
具体的实现:
OperationFactory类:
把原本在客户端的判断,放到了工厂类中,客户端只需要传递条件便可以得到对应的产品,同时也去除了客户端和具体产品的依赖。客户端只需要和工厂类和抽象产品类交互。(客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量)
public class OperationFactory {
public static Operation createOperation(String operate){
Operation operation = null;
switch(operate){
case "+":
operation = new OperationAdd();
break;
case "-":
operation = new OperationSub();
break;
case "*":
operation = new OperationMul();
break;
case "/":
operation = new OperationDiv();
break;
}
return operation;
}
}
Operation类:
public abstract class Operation {
protected double numberA;
protected double numberB;
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
public abstract double getResult();
}
加法类OperationAdd类:
public class OperationAdd extends Operation{
@Override
public double getResult() {
return numberA+numberB;
}
}
减法类OperationSub类:
public class OperationSub extends Operation{
@Override
public double getResult() {
return numberA-numberB;
}
}
乘法类OptionSub类:
public class OperationMul extends Operation{
@Override
public double getResult() {
return numberA*numberB;
}
}
除法类OptionDiv类:
public class OperationDiv extends Operation{
@Override
public double getResult() {
if(numberB==0){
try {
throw new Exception("除数不能为0");
} catch (Exception e) {
e.printStackTrace();
}
}
double result = numberA/numberB;
return result;
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
Operation operation = OperationFactory.createOperation("/");
operation.setNumberA(10);
operation.setNumberB(2);
System.out.println("result="+operation.getResult());
}
}
客户端需要知道的类
简单工厂类(OperationFactory)、产品抽象类(Operation);