简单工厂模式
概述:
简单工厂模式,又被称之为“静态工厂方法”模式,该模式会专门定义一个“工厂类”,然后子啊工厂类提供一个静态方法,有该静态方法根据用户的输入,动态决定创建什么类型的对象。通常来说:工厂类的产生的对象,都有一个特点,具备相同的父类,或者具备相同的接口。
简单工厂的3种角色
简单工厂的3中角色是工厂类,产品的抽象类(借口),具体的产品
工厂类:主要负责根据用户的输入,动态的产生具体的产品
产品抽象类|接口:对具体产品进行抽象
具体的产品:工厂类产生的具体实例
简单工厂模式的作用
将客户调用类的职责分离,每个客户调用类身上至少具备2个职责(创建对象的职责,调用对象行为的职责),进行职责分离,让调用类最终只存在1个职责(调用对象的行为的职责),而将创建对象的职责委托给工厂类。
简单工厂模式的缺点
简单工厂,实际上将对象的产生,由之前的客户调用类身上,强制性的定义在工厂类身上,工厂类此时具备一定的创建对象的业务逻辑,以及一些判断逻辑。那么如果具体的产品,需要发生变化,或者有新的产品需要扩展,那么毫无疑问,此时就需要去针对工厂类做相应的变化,那么无形当中就违背了"开闭原则" , “单一原则" , "依赖倒转原则”。
注意:简单工厂模式,只能产生同意家族的产品非同一家族的产品,管单工厂是无法使用的.
案例:
我们需要对一个数进行加减乘除运算,如a+b,a*b,a/b,a%b,根据用户选择决定运算类型。
思考解决步骤如下:
(1)书写一个计算能力的接口
(2)书写加减乘除的计算类,实现接口
(3)调用接口的方法
代码如下:
(1)
/**
* 计算能力接口
* @author pxb
*
*/
public interface Calculateable {
/**
* 具有计算能力的一个方法
* @param a
* @param b
* @return
*/
int calculate(int a,int b);
}
(2)具体方法
/**
* 加法计算类
* @author Administrator
*
*/
public class AddCalculate implements Calculateable {
@Override
public int calculate(int a, int b) {
// TODO Auto-generated method stub
return a + b;
}
}
/**
* 减法计算类
* @author Administrator
*
*/
public class SubCalculate implements Calculateable {
@Override
public int calculate(int a, int b) {
// TODO Auto-generated method stub
return a - b;
}
}
/**
* 乘法计算类
* @author Administrator
*
*/
public class MulCalculate implements Calculateable {
@Override
public int calculate(int a, int b) {
// TODO Auto-generated method stub
return a * b;
}
}
其他方法与上一致,此处就不赘述!
(3)执行主方法
由于我们无法得知用户想要的运算方式,所以需要一个判断,再创建对应的对象。
代码如下:
public static void main(String[] args) {
// TODO Auto-generated method stub
int a = 10;
int b = 5;
int c = 0;
String str = "-";
Calculateable calculate=null;
switch (str) {
case "+":
calculate=new AddCalculate;
c = calculate.calculate(a, b);
break;
case "-":
calculate=new SubCalculate;
c = calculate.calculate(a, b);
break;
case "*":
calculate=new MulCalculate ;
c = calculate.calculate(a, b);
break;
default:
break;
}
System.out.println(c);
}
通过运行,我们发现确实实现了计算,但我们可以在main函数中,发现此时的调用类,首先是创建对象,然后执行方法,违背了单一原则和开闭原则,比如以后还要加上其他的一些计算,需要修改。此时我们的思考就是能不能有一个专门的东西来做这件事,这个想法很对,我们可以专门写一个产生对象的工具类。
代码如下:
/**
* 简单工厂
* @param str
* @return
*/
public static Calculateable production(String str) {
Calculateable calc = null;
/*
* 违背开闭原则(扩展新的,需要修改原来的代码)
*/
switch (str) {
case "+":
calc = new AddCalculate();
break;
case "-":
calc = new SubCalculate();
break;
case "*":
calc = new MulCalculate();
break;
case "/":
calc = new DivCalculate();
break;
case "%":
calc = new ModCalculate();
break;
default:
break;
}
return calc;
}
主方法如下:
/**
* 客户调用类
* @author Administrator
*
*/
public class MainEnter {
public static void main(String[] args) {
try {
/*
* 此时的问题:客户调用类和工厂类之间,直接发生耦合
*/
//静态工厂模式的代码实现
Calculateable calc = CalculateFactory.production("*");
System.out.println(calc.calculate(10, 5));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
通过简单工厂模式,是main方法类职责单一化,但仍存在客户调用类和工厂类之间直接发生耦合,解决方式在下一文抽象工厂会讲到!