您的位置:首页 > 编程语言

改良用简单工厂模式构造的计算器代码—“反射”技术

2016-06-25 17:45 411 查看
出处:http://blog.csdn.net/newjueqi/archive/2009/04/18/4089233.aspx

【文章标题】改良用简单工厂模式构造的计算器代码—“反射”技术

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ】190678908

【作者博客】http://blog.csdn.net/newjueqi

【编程环境】JDK 1.6.0_01

【作者声明】欢迎转载文章,但转载请保留文章的完整性以及注明文章的出处。

*******************************************************************************

《大话设计模式》中的第一章是一个用简单工厂模式构建的简易计算器的例子,在书中的P10-P11页中有个工厂类OperaationFactory用来构造各个运算类的实例,内容如下:

//输入运算符符号,工厂就实例化合适的对象,通过多态,返回父类的方式实现了计算器的效果

public class OperaationFactory

{

public static Operation createOperate(string operate)  //传入需要选择的运算类型

{

Operation oper=null;

switch(operate)

{

case "+":

oper=new OperationAdd();

break;

case "-":

oper=new OperationSub();

break;

case "*":

oper=new OperationMul();

break;

case "/":

oper=new OperationDiv();

break;

}

return opr;

}

}

但这里有个问题:如果需要增加新的运算类,除了要修改界面的代码,还要在OperaationFactory的switch中增加新的语句!!!其实用“反射”就能很好地解决这个问题(注意:《大话设计模式》一书中是C#代码,而本文修改的代码是用java实现的,请注意两者在实现上的区别)。

“反射”技术就是把类的各个组成部分都映射成对象,利用“反射”技术可以传入的字符串作为参数,创建类的实例对象,简单解释一下需要用到的两个函数:

(1)forName()

static Class<?> forName(String className) 

className:类名

返回值:className的类对象

(2)newInstance()

作用:通过类的对象创建一个类的实例

用java改写后的工厂类OperaationFactory的代码如下:

////输入运算符符号,工厂就实例化合适的对象,通过多态,返回父类的方式实现了计算器的效果

class OperaationFactory

{

//传入需要构造的运算类的类名

public Operation createOperate(string operatstring) 

{

Operat oper=null;

//获取了运算类的类对象

Class cla=Class.forName(operatstring );

//获取了运算类的实例对象,返回类型为Object

Object obj=cla.newInstance();

//强制类型转换

oper=(Operat)obj;

return oper;

}

}

下面给用java 修改后的代码:

//算法的抽象类

abstract class Operat

{

protected double numberA=0.0;

protected double numberB=0.0;

//设置要参与加法运算的两个数的值

public void setNumber( double numberA, double numberB )

{

this.numberA=numberA;

this.numberB=numberB;

}

//获取运算的结果

public abstract double getResult();

}

//加法,具体的算法类,继承于算法的抽象类Operat

class OperAdd extends Operat

{

//获取运算的结果

public double getResult()

{

return numberA+numberB;

}

}

//减法,具体的算法类,继承于算法的抽象类Operat

class OperSub extends Operat

{

//获取运算的结果

public double getResult()

{

return numberA-numberB;

}

}

//下面是测试的代码

class Test

{

public static void main( String args[] )throws Exception

{

System.out.println( "请输入运算类型:" );

//传入需要执行的运算类型,必须为类名

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String opsel=br.readLine();

//创造工厂类的实例

OperaationFactory opfactory=new OperaationFactory();

//通过父类访问子类的方法

Operat op=opfactory.createOperate( opsel );

System.out.print("输入运算的第1数:");

BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));

double numberA = Double.parseDouble(br.readLine());

System.out.print("输入运算的第2数:");

BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));

double numberB = Double.parseDouble(br.readLine());

//设置要参与加法运算的两个数的值

op.setNumber( numberA, numberB );

//输出结果

System.out.println( "结果是:"+op.getResult() );

}

}

程序运行结果如图1:

                      


                                               图1

其中红框①部分一般是通过界面编程作为参数传入的,不需要使用者知道加法对应的是哪个类,界面编程的伪代码表示如下:

Switch( 用户选择的运算类型 )

{

Case “加法”:

输入的参数为:OperAdd

Break;

Case “减法”:

输入的参数为:OperSub

Break;

}

下面通过一个新的需求体会一下“反射”的好处,假设要增加一个乘法的运算,我们只需要做以下几步:

1. 增加一个乘法类继承Operat类,代码的定义如下:

//乘法,具体的算法类,继承于算法的抽象类Operat

class OperMul extends Operat

{

//获取运算的结果

public double getResult()

{

return numberA*numberB;

}

}

2. 然后把编译好的字节码文件放在工作目录下,如图2:

                                


图2

3. 运行程序,如图3:

                                      


图3

大家可以看到,我们需要为程序添加一个计算乘法的功能,只需要单独写一个乘法类,以前写的逻辑代码全部都不需要改都不需要改(当然,需要修改界面代码增加乘法的选项)。通过使用“反射”技术,更加体现了面向对象中的“强内聚,弱耦合”和“开发封闭原则”。

更多0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: