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

 出处: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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值