zoukankan      html  css  js  c++  java
  • 简单工厂模式

    使用简单工厂模式实现一个计算器功能

    一、过程化设计

    主方法如下:

     1 import java.io.BufferedReader;
     2 import java.io.IOException;
     3 import java.io.InputStreamReader;
     4 
     5 
     6 public class Computer {
     7     
     8     /**
     9      * @param args
    10      * @throws IOException 
    11      */
    12     public static void main(String[] args) throws IOException {
    13         // TODO Auto-generated method stub
    14         System.out.println("请输入数字1:");
    15         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    16         String strNumA = br.readLine();
    17         System.out.println("请输入运算符:");
    18         br = new BufferedReader(new InputStreamReader(System.in));
    19         String strOperator = br.readLine();
    20         System.out.println("请输入数字2:");
    21         br = new BufferedReader(new InputStreamReader(System.in));
    22         String strNumB = br.readLine();
    23         String strResult = "";
    24         try {
    25             if (StringConst.Plus.equals(strOperator)) {
    26                 strResult = String.valueOf(Double.parseDouble(strNumA) + Double.parseDouble(strNumB));
    27             }
    28             else if (StringConst.Minus.equals(strOperator)) {
    29                 strResult = String.valueOf(Double.parseDouble(strNumA) - Double.parseDouble(strNumB));
    30             }
    31             else if (StringConst.Multiply.equals(strOperator)) {
    32                 strResult = String.valueOf(Double.parseDouble(strNumA) * Double.parseDouble(strNumB));
    33             }
    34             else if (StringConst.Except.equals(strOperator)) {
    35                 if ("0".equals(strNumB)) {
    36                     System.out.println("除数不能为0,请检查!");
    37                     return;
    38                 }
    39                 strResult = String.valueOf(Double.parseDouble(strNumA) / Double.parseDouble(strNumB));
    40             }
    41             else {
    42                 System.out.println("您输入的运算符不正确,请检查!");
    43                 return;
    44             }
    45         }
    46         catch (NumberFormatException ex){
    47             System.out.println("您输入的数据不正确,请检查!");
    48             return;
    49         }
    50         catch (Exception ex) {
    51             System.out.println(ex.getMessage());
    52             System.out.println("----------------------------------------");
    53             System.out.println(ex.getStackTrace());
    54         }
    55         System.out.println("运算结果为:"+strResult);
    56     }
    57 }
    View Code

    常量定义如下:

    1 public class StringConst {
    2     public static final String Plus = "+";
    3     
    4     public static final String Minus = "-";
    5     
    6     public static final String Multiply = "*";
    7     
    8     public static final String Except = "/";
    9 }
    View Code

    二、面向对象设计

    下面将围绕面向对象编程三大特征:封装、继承、多态对上面代码进行优化。

    1.首先使用封装对上面过程化的代码进行修改,通过封装可以将实现功能的业务逻辑与界面显示分离开来,界面只需要展示计算的结果,不需要关心如何去实现的细节,而具体是怎么计算的则交给单独的一个类去处理,从而降低了具体实现代码与界面之间的耦合,同时还可以将具体实现的代码可以应用到不同项目中,如:网站,移动平台等等,从另一方面也提高了代码的复用,也就是代码的可重用性提高了。

    修改后的主方法如下:

     1 import java.io.BufferedReader;
     2 import java.io.IOException;
     3 import java.io.InputStreamReader;
     4 
     5 
     6 public class Computer {
     7     
     8     /**
     9      * @param args
    10      * @throws IOException 
    11      */
    12     public static void main(String[] args) throws IOException {
    13         // TODO Auto-generated method stub
    14         System.out.println("请输入数字1:");
    15         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    16         String strNumA = br.readLine();
    17         System.out.println("请输入运算符:");
    18         br = new BufferedReader(new InputStreamReader(System.in));
    19         String strOperator = br.readLine();
    20         System.out.println("请输入数字2:");
    21         br = new BufferedReader(new InputStreamReader(System.in));
    22         String strNumB = br.readLine();        
    23         System.out.println("运算结果为:"+ComputerHelper.getResults(strNumA, strOperator, strNumB));
    24         
    25     }
    26 }
    View Code

    辅助类的类定义如下:

     1 public class ComputerHelper {
     2     public static String getResults(String strNumA, String strOperator, String strNumB) {
     3         String strResult = "";
     4         try {
     5             if (StringConst.Plus.equals(strOperator)) {
     6                 strResult = String.valueOf(Double.parseDouble(strNumA) + Double.parseDouble(strNumB));
     7             }
     8             else if (StringConst.Minus.equals(strOperator)) {
     9                 strResult = String.valueOf(Double.parseDouble(strNumA) - Double.parseDouble(strNumB));
    10             }
    11             else if (StringConst.Multiply.equals(strOperator)) {
    12                 strResult = String.valueOf(Double.parseDouble(strNumA) * Double.parseDouble(strNumB));
    13             }
    14             else if (StringConst.Except.equals(strOperator)) {
    15                 if ("0".equals(strNumB)) {                    
    16                     return "除数不能为0,请检查!";
    17                 }
    18                 strResult = String.valueOf(Double.parseDouble(strNumA) / Double.parseDouble(strNumB));
    19             }
    20             else {                
    21                 return "您输入的运算符不正确,请检查!";
    22             }
    23         }
    24         catch (NumberFormatException ex){            
    25             return "您输入的数据不正确,请检查!";
    26         }
    27         catch (Exception ex) {
    28             System.out.println(ex.getMessage());
    29             System.out.println("----------------------------------------");
    30             System.out.println(ex.getStackTrace());
    31         }
    32         return strResult;
    33     }
    34 }
    View Code

     2.下面将从继承的角度来分析这个辅助类,从这个辅助类中的if条件判断中可以看出+、-、×、/这四个运算符之间所共有的属性,如:都有2个参加运算的数值和1个返回结果,因此不难想到可以建一个父类,在父类的定义中包含这2个参加运算的数值和1个返回结果的方法,而+、-、×、/可以建立成这个父类的子类,通过继承可以获得父类所定义的属性,同时还可以复写父类的方法,通过继承,可以减少开发过程中的冗余代码,避免了属性在子类中重复定义以及相同功能方法的定义,这些公共的部分都可以提取到父类当中,从而提高了代码的复用。

    父类定义如下:

    1 public class Operator {
    2     public String strNumA;
    3     
    4     public String strNumB;
    5     
    6     public String getResults(){
    7         return "";
    8     }
    9 }
    View Code

    四个子类定义如下:

     1 public class PlusOperator extends Operator{
     2     
     3     public String getResults() {
     4         
     5         String strResult = "";
     6         
     7         try {
     8             strResult = String.valueOf(Double.parseDouble(strNumA) + Double.parseDouble(strNumB));            
     9         }
    10         catch (NumberFormatException ex){            
    11             return "您输入的数据不正确,请检查!";
    12         }
    13         catch (Exception ex) {
    14             System.out.println(ex.getMessage());
    15             System.out.println("----------------------------------------");
    16             System.out.println(ex.getStackTrace());
    17         }
    18         
    19         return strResult;
    20     }
    21 }
    22 
    23 
    24 public class MinusOperator extends Operator{
    25 
    26     public String getResults() {
    27         
    28         String strResult = "";
    29         
    30         try {
    31             strResult = String.valueOf(Double.parseDouble(strNumA) - Double.parseDouble(strNumB));            
    32         }
    33         catch (NumberFormatException ex){            
    34             return "您输入的数据不正确,请检查!";
    35         }
    36         catch (Exception ex) {
    37             System.out.println(ex.getMessage());
    38             System.out.println("----------------------------------------");
    39             System.out.println(ex.getStackTrace());
    40         }
    41         
    42         return strResult;
    43     }
    44 
    45 }
    46 
    47 
    48 public class MultiplyOperator extends Operator{
    49 
    50     public String getResults() {
    51         
    52         String strResult = "";
    53         
    54         try {
    55             strResult = String.valueOf(Double.parseDouble(strNumA) * Double.parseDouble(strNumB));            
    56         }
    57         catch (NumberFormatException ex){            
    58             return "您输入的数据不正确,请检查!";
    59         }
    60         catch (Exception ex) {
    61             System.out.println(ex.getMessage());
    62             System.out.println("----------------------------------------");
    63             System.out.println(ex.getStackTrace());
    64         }
    65         
    66         return strResult;
    67     }
    68 }
    69 
    70 
    71 public class ExceptOperator extends Operator{
    72     
    73     public String getResults() {
    74         
    75         String strResult = "";
    76         
    77         try {
    78             if ("0".equals(strNumB)) {
    79                 return "除数不能为0,请检查!";
    80             }
    81             
    82             strResult = String.valueOf(Double.parseDouble(strNumA) / Double.parseDouble(strNumB));        
    83         }
    84         catch (NumberFormatException ex){            
    85             return "您输入的数据不正确,请检查!";
    86         }
    87         catch (Exception ex) {
    88             System.out.println(ex.getMessage());
    89             System.out.println("----------------------------------------");
    90             System.out.println(ex.getStackTrace());
    91         }
    92         
    93         return strResult;
    94     }
    95 }
    View Code

    3.最后再从多态的角度去继续完善这个计算器的功能,所谓的多态也就是编译时的类型与实际运行的类型不一致的场合,可以简单的理解为父类 变量名 = new 子类();

    此时也就出现了多态,有了对多态的理解,就可以创建工厂类根据不同的运算符构造出不同的对象。通过多态,可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。对于后续计算器中要实现log,sin,tan等等的功能,就可以创建相应的子类以及在工厂类中再添加一个判断就可以了,当然这种添加判断就违背了开放-闭合的原则,因此出现了工厂方法模式,就避免了这种弊端。

    工厂类的定义如下:

     1 public class OperatorFactory {
     2 
     3     public static Operator getOperator(String Operator) {
     4         
     5         if (StringConst.Plus.equals(Operator)) {            
     6             return new PlusOperator();
     7         }else if (StringConst.Minus.equals(Operator)) {            
     8             return new MinusOperator();
     9         }else if (StringConst.Multiply.equals(Operator)) {            
    10             return new MultiplyOperator();
    11         }
    12         else if (StringConst.Except.equals(Operator)) {            
    13             return new ExceptOperator();
    14         }
    15         else {
    16             return null;
    17         }
    18     }
    19 }
    View Code

    有了工厂类以后,就可以在主函数中根据用户的选择来通过工厂类创造出(new)不同的子类,利用多态的特性实现计算结果的功能。

    修改后的主函数如下:

     1 import java.io.BufferedReader;
     2 import java.io.IOException;
     3 import java.io.InputStreamReader;
     4 
     5 
     6 public class Computer {
     7     
     8     /**
     9      * @param args
    10      * @throws IOException 
    11      */
    12     public static void main(String[] args) throws IOException {
    13         // TODO Auto-generated method stub
    14         System.out.println("请输入数字1:");
    15         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    16         String strNumA = br.readLine();
    17         System.out.println("请输入运算符:");
    18         br = new BufferedReader(new InputStreamReader(System.in));
    19         String strOperator = br.readLine();
    20         System.out.println("请输入数字2:");
    21         br = new BufferedReader(new InputStreamReader(System.in));
    22         String strNumB = br.readLine();            
    23         
    24         if (null == OperatorFactory.getOperator(strOperator)) {
    25             System.out.println("您输入的运算符不正确,请检查!");
    26             return;
    27         }
    28         
    29         Operator operator = OperatorFactory.getOperator(strOperator);
    30         operator.strNumA = strNumA;
    31         operator.strNumB = strNumB;
    32         System.out.println("运算结果为:"+operator.getResults());
    33     }
    34 }
    View Code

    三、总结

    至此,由一个面向过程设计的代码被修改成了面向对象设计的代码,主要是通过面向对象的三大特征:封装、继承、多态来改善了代码,简单工厂模式的宗旨也就是通过工厂类创造出(new)不同的对象,希望今后能够多运用“面向对象的思想”去思考程序,设计出优秀的程序。

  • 相关阅读:
    在类中声明常量
    PHPStudy配置虚拟主机配置域名步骤
    PHPStudy配置虚拟主机步骤
    2019年7月22日星期一,简单的总结一下
    简单的面向对象
    session和cookie
    Jquery 事件绑定 bind 与on 的区别
    php try catch用法
    include,include_once,require,require_once的区别
    require与 include区别
  • 原文地址:https://www.cnblogs.com/buguangchao/p/3319726.html
Copyright © 2011-2022 走看看