今天和大家分享一下设计模式中的 简单工厂 工厂方法 抽象工厂
上图是工厂模式百度百科的截图,工厂模式(三种模式)的目的在于程序的可扩展性,便于维护,减少开发出错,本人总结为工厂模式就是让类的创建和使用分离,降低程序模块之间的耦合程度(欢迎提出质疑)
1.简单工厂模式(Simple Factory Pattern)
我这里来拿《大话设计模式》中“大鸟”指导“小菜”完成的一个简单工厂来举例子(编写一个简单的计算器程序),这里我把他的c#代码换成了本人学习的java -- ps:本人也是刚毕业不久的菜鸟一枚,正在看这本书就当是写个个人总结和大家分享一下。这本书评价不错京东有正版有能力的朋友可以支持一下作者。也可以看网络上的pdf.....
首先来分析一下计算器程序的目的是为了得到一个计算结果,我们应该抽象出这个结果首先我们是我们的抽象接口代码
public interface Operation {
public double getResult(double number_a,double number_b);
}
Operation 接口中一个getResult 参数为 两个double数。
假设目前只要满足 + - * /的计算 好了我们来新建四个计算的运算类分别实现接口Operation
public class OperationAdd implements Operation{
@Override
public double getResult(double number_a, double number_b) {
double result=0;
result= number_a+number_b;
return result;
}
}
public class OperationMul implements Operation{
@Override
public double getResult(double number_a,double number_b) {
double result=0;
result=number_a*number_b;
return result;
}
}
public class OperationSub implements Operation{
@Override
public double getResult(double number_a,double number_b) {
double result=0;
result= number_a-number_b;
return result;
}
}
public class OperationDiv implements Operation{
@Override
public double getResult(double number_a,double number_b) {
double result=0;
if(number_b==0)
{
try {
throw new Exception("除数不能为零");
} catch (Exception e) {
e.printStackTrace();
}
}
result=number_a/number_b;
return result;
}
}
这里大家是不是万事具备只欠东风了呢,问题来了具体的运算类怎么调用 何时调用谁呢,这时间我们把我们的重点工厂类请出来了,让它决定我们怎么使用具体的运算类
public class OperationFactory {
private static OperationFactory instance ;
private OperationFactory(){}
public static OperationFactory getInstance(){
if (instance == null) {
synchronized (OperationFactory.class){
if (instance == null) {
instance = new OperationFactory();
}
}
}
return instance ;
}
public Operation createOperation(String operator){
Operation operation=null;
switch (operator)
{
case "+":
operation=new OperationAdd();
break;
case "-":
operation=new OperationSub();
break;
case "*":
operation=new OperationMul();
break;
case "/":
operation=new OperationDiv();
break;
default:
try {
throw new Exception("请输入正确的运算符");
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return operation;
}
public Operation makeOperation(Class c)
{
Operation operation=null;
try {
operation=(Operation) Class.forName(c.getName()).newInstance();
}catch (InstantiationException e) {
System.out.println("不支持抽象类或接口");
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
System.out.println("没有足够权限,即不能访问私有对象");
} catch (ClassNotFoundException e) {
System.out.println("类不存在");
e.printStackTrace();
} catch (ClassCastException e)
{
System.out.println("选择的类不正确");
}
return operation;
}
}
我们先不管makeOperation方法先看createOperation方法。
createOperation只需要在调用的时间接受operator参数(+-*/)就能返回所对应的运算类了
下面是客户端代码
public class Main {
public static void main(String[] args) {
Operation operation;
operation=OperationFactory.getInstance().createOperation("+");
System.out.println(operation.getResult(1,1));
}
}
不用我说输出结果为2
这里我们利用java的多态性调用了OperationAdd 类的getResult方法传入了1 和1
但是怎么创建的OperationAdd 我们并没有去管。这就是简单工厂的一个实例了
也许大家会认为这么设计出来的计算器程序应该很完美了吧,然而并不是。
没有遵守开放—封闭原则。所谓的“开放-封闭”原则就是开放接口,封闭修改。如果将来需要添加一个开方的算法,那么,在简单工厂模式中,就必须在简单工厂类中添加相应的判断语句。前面说的必须也不是那么绝对,这时我们再看工厂类中的makeOperation 方法 如果要加入一个开方的运算类,我们不改工厂类的逻辑是可以通过newInstance调用这个新的开方运算律但是 newInstance是弱类型。所以想完全的按照开放—封闭原则我们还是要来看一下工厂方法模式
优点
简单工厂顾名思义就是你只管调用操作不需要管创建类的过程所以叫简单工厂(根据客户端的选择条件动态实例化相关的类,对客户端调用来说除去了与具体产品的依赖)因为创建的逻辑交给了工厂类,相当于就是给类的创建做了封装。
缺点
简单工厂没有遵守开放—封闭原则。所谓的“开放-封闭”原则就是开放接口,封闭修改。如果将来需要添加一个开方的算法,那么,在简单工厂模式中,就必须在简单工厂类中添加相应的case语句!
2. 工厂方法模式
晚上更新
3. 抽象工厂模式
晚上更新