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

 

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

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ190678908

【作者博客】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;     

       }

}

 

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

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

1forName()

static Class<?>

forName(String className)

className:类名

返回值:className的类对象

 

2newInstance()

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

 

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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newjueqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值