[java] 汇率换算器实现(1)


 

[java] 汇率换算器实现(1)

 

[java] 汇率换算器实现(1)

1 问题描述

实现不同货币之间的汇率换算.

名词: 货币, 汇率

动词: 换算

2 类设计

class list:

  1. Money
    • double amount: 货币的数量
    • String unit: 货币的单位
  2. Rate
    • private Hashtable rateTable: 用来存储不同货币之间的汇率

3 初步实现

 

3.1 建立项目目录结构

       .
       ├── build.xml
       ├── lib
       │   ├── hamcrest-core.jar
       │   └── junit.jar
       ├── README.txt
       ├── run
       └── src
           └── com
               └── cnblogs
                   └── grassandmoon

其中, build.xml为ant执行所需的配置文件. run为shell文件, 用于运行编译后的java程序.

build.xml文件内容如下:

 1 <?xml version="1.0"?>
 2 
 3 <!-- build.xml - a simple Ant buildfile -->
 4 <project name="javacookbook" default="all" basedir=".">
 5 
 6   <!-- The directory containing source code -->
 7   <property name="src.dir" value="src"/>
 8   <property name="lib.dir" value="lib"/>
 9 
10   <!-- Temporary build directories -->
11   <property name="build.dir" value="build"/>
12   <property name="build.classes" value="${build.dir}/classes"/>
13 
14   <property name="java.lib" value="${java.home}/jre/lib/rt.jar"/>
15 
16   <!-- Target to create the build directories prior to the -->
17   <!-- compile target. -->
18   <target name="prepare">
19     <mkdir dir="${build.dir}"/>
20     <mkdir dir="${build.classes}"/>
21   </target>
22 
23   <target name="all" depends="project"/>
24 
25   <target name="project" depends="prepare">
26     <javac srcdir="${src.dir}"
27  destdir="${build.classes}"
28  classpath="${java.lib}:${lib.dir}/junit.jar:${build.classses}"
29  debug="on"
30  includeantruntime="on"/>
31   </target>
32 
33   <target name="clean" description="Remove all generated files.">
34     <delete dir="${build.dir}"/>
35   </target>
36 </project>

 

3.2 建立测试文件

 /** TestRate.java
  * 用于货币汇率转换工具的测试
  */
 package com.cnblogs.grassandmoon;
 
 import static org.junit.Assert.assertEquals;
 import org.junit.Test;
 
 public class TestRate {
     @Test
     public void testGetRate() {
         Money m = new Money(150, "USD");
 
         Rate.setRate("USD", "CNY", 6.25);
         Money mCNY = Rate.exchangeRate(m, "CNY");
 
         assertEqual(new Money(150*6.25, "CNY"), mCNY);
     }
}

3.3 对应的实现文件, Money

package com.cnblogs.grassandmoon;

import java.util.*;

class Rate {
    // 利用hashtable对不同货币之间的利率进行存储
    //   key: $from+$to, value: $rate
    private static Hashtable rateTable = new Hashtable();

    // 设置不同货币之间的利率
    //    1 $from * $rate = 1 $to
    public static void setRate(String from, String to, double rate) {
        rateTable.put(from+to, new Double(rate));
    }

    private static double getRate(String key) {
        Double db = (Double) rateTable.get(key);
        return db.doubleValue();
    }

    // 将一定量的货币$m, 转变成单位为$to的货币量
    // return: 相应的货币值
    public static Money exchangeRate(Money m, String to) {
        if (m.unit == to) return new Money(m);
        String key = m.unit + to;
        double rate = getRate(key);
        return new Money(m.amount*rate, to);
    }
}

public class Money {
    double amount;
    String unit;

    public Money(double amount, String unit) {
        setMoney(amount, unit);
    }

    public Money(Money m) {
        setMoney(m.amount, m.unit);
    }

    public void setMoney(double amount, String unit) {
        this.amount = amount;
        this.unit = unit;
    }

    public boolean equals(Object obj) {
        Money other = (Money) obj;
        return amount == other.amount
            && unit.equals(other.unit);
    }
}

3.4 增加输入输出: 一般化

有哪些内容需要进行输入输出呢?

输入

  • 欢迎信息
    欢迎使用汇率转换器
    版本: 1.0
    
    作者: 钟谢伟
    
  • 帮助信息
    1. 输入不同货币以及对应的汇率信息, 
       第一个为需要转换的货币单位
       第二个为转换到的目标货币单位
       第三个为相应的汇率
       不同项目之间用空格隔开
       如: USD CNY 6.25
       表示: 1 USD * 6.25 = 1 CNY
    
    2. 输入待转换量, 用空格隔开
       如: 150 USD
    
    3. 帮助
    
    4. 退出
    请进行选择 (1, 2, 3 or 4)
    
  • 不同货币单位以及相应的汇率
  • 需要进行转换的货币量

输出

  • 转换后的结果
    如: 150 USD = 937.50 CNY
    

3.5 对应的实现, MoneyDemo

3.6 小结

目前已经完成的功能:

  • 人为的输入汇率
  • 根据输入的汇率进行转换

需要进一步增加的功能:

  • 当输入错误时, 如何进行处理?
  • 当需要转换的货币单位, 没有在汇率表中时, 如何进行处理?
  • 如何克服每次手动增加汇率的麻烦之处?

下面将根据上述的问题进行进一步的改进.

4 进一步的改进

 

4.1 输入格式统一以及错误处理

为了减少代码的重复量, 需要对汇率输入, 以及转换输入的格式进行统一, 如下:

  • 汇率输入: 汇率 from币种 to币种, 如 6.25 USD CNY
  • 转换输入: from币种货币量 from币种 to币种, 如 100 USD CNY

然后对输入的错误情况进行了处理:

  • 格式错误
  • 汇率转换过程中遇到没有相应的汇率信息的情况处理

此时的结果如下: #中间代码

 1 // MoneyDemo.java
 2 package com.cnblogs.grassandmoon;  3 
 4 import java.io.*;  5 
 6 class Helper {  7     public static void printVersion() {  8         System.out.println("欢迎使用汇率转换器");  9         System.out.println("版本: 1.0");  10  System.out.println();  11         System.out.println("作者: 钟谢伟");  12         System.out.println("email: grass-of-sky@163.com");  13  System.out.println();  14  }  15 
 16     public static void printHelp() {  17         System.out.println("1. 输入不同货币以及对应的汇率信息,");  18         System.out.println("   第一个为相应的汇率");  19         System.out.println("   第二个为需要转换的货币单位");  20         System.out.println("   第三个为转换到的目标货币单位");  21         System.out.println("   不同项目之间用空格隔开");  22         System.out.println("   " + getRateUsage());  23         System.out.println("   表示: 1 USD * 6.25 = 1 CNY");  24  System.out.println();  25         System.out.println("2. 输入待转换量, 用空格隔开");  26         System.out.println("   " + getExchangeUsage());  27  System.out.println();  28         System.out.println("3. 帮助");  29  System.out.println();  30         System.out.println("4. 退出");  31  System.out.println();  32  printUsage();  33  System.out.println();  34  }  35 
 36     public static void printUsage() {  37         System.out.println("请选择 (1, 2, 3 或者 4)");  38  }  39 
 40     public static String getRateUsage() {  41         return "如: 6.25 USD CNY";  42  }  43 
 44     public static String getExchangeUsage() {  45         return "如: 100 USD CNY";  46  }  47 }  48 
 49 class ReadLineTokens {  50     public double value;  51     public String from;  52     public String to;  53 
 54     ReadLineTokens(double v, String f, String t) {  55         value = v;  56         from = f;  57         to = t;  58  }  59 }  60 
 61 public class MoneyDemo {  62     // 对汇率输入, 以及转换输入进行处理, 提取不同的成份
 63     static ReadLineTokens processReadLine(BufferedReader br)  64     throws IOException {  65         String inputLine = br.readLine();  66         String tokens[] = inputLine.split(" ");  67         if (tokens.length == 1 && tokens[0].equals("q")) {  68             return null;  69  }  70 
 71         return new ReadLineTokens(new Double(tokens[0]),  72                                   tokens[1],  73                                   tokens[2]);  74  }  75 
 76     public static void main(String[] args)  77     throws IOException {  78         String cmdLine = null;  79         String inputMsg = null;  80         Money m = new Money();  81         Money exchanged = new Money();  82  ReadLineTokens tokens;  83         boolean inputError = false;  84         BufferedReader br = new
 85             BufferedReader(new InputStreamReader(System.in));  86  Helper.printVersion();  87  Helper.printHelp();  88 
 89         while (true) {  90             cmdLine = br.readLine();  91             if (cmdLine.equals("1")) {  92                 do {  93                     try {  94                         System.out.print("输入汇率关系 " +
 95                                          Helper.getRateUsage() +
 96                                          " (退出当前选项 \"q\"): ");  97 
 98                         // input "q" to quick this step
 99                         tokens = processReadLine(br); 100                         if (tokens == null) { 101                             break; 102  } 103 
104  Rate.setRate(tokens.from, tokens.to, tokens.value); 105  System.out.println(); 106                         inputError = false; 107                     } catch (Exception e) { 108                         System.out.println("\n\t请按照正确的格式进行输入\n"); 109                         inputError = true; 110  } 111                 } while (inputError); 112             } else if (cmdLine.equals("2")) { 113                 do { 114                     try { 115                         System.out.print("输入待转换量 " +
116                                          Helper.getExchangeUsage() +
117                                          " (退出当前选项 \"q\"): "); 118 
119                         // input "q" to quit this step
120                         tokens = processReadLine(br); 121                         if (tokens == null) { 122                             break; 123  } 124 
125  m.setMoney(tokens.value, tokens.from); 126                         exchanged = Rate.exchangeRate(m, tokens.to); 127                         System.out.println(m + " = " + exchanged); 128  System.out.println(); 129                         inputError = false; 130                     } catch (IllegalArgumentException e) { 131                         System.out.println("\n\t汇率转换表中没有相应的转换项\n"); 132                         inputError = true; 133                     } catch (Exception e) { 134                         System.out.println("\n\t请按照正确的格式进行输入\n"); 135                         inputError = true; 136  } 137                 } while (inputError); 138             } else if (cmdLine.equals("3")) { 139  Helper.printHelp(); 140             } else if (cmdLine.equals("4")) { 141                 break; 142             } else { 143  Helper.printUsage(); 144  } 145  } 146  } 147 } 148 
149 // Money.java
150 package com.cnblogs.grassandmoon; 151 
152 import java.util.*; 153 
154 class Rate { 155     // 利用hashtable对不同货币之间的利率进行存储 156     // key: $from+$to, value: $rate
157     private static Hashtable rateTable = new Hashtable(); 158 
159     // 设置不同货币之间的利率 160     // 1 $from * $rate = 1 $to
161     public static void setRate(String from, String to, double rate) { 162         rateTable.put(from+to, new Double(rate)); 163  } 164 
165     // 将一定量的货币$m, 转变成单位为$to的货币量 166     // return: 相应的货币值
167     public static Money exchangeRate(Money m, String to) { 168         if (m.unit.equals(to)) return new Money(m); 169         String key = m.unit + to; 170         Double rate = (Double) rateTable.get(key); 171 
172         if (rate == null) { 173             throw new IllegalArgumentException(); 174  } 175 
176         return new Money(m.amount*rate.doubleValue(), to); 177  } 178 } 179 
180 public class Money { 181     double amount; 182  String unit; 183 
184     public String toString() { 185         return amount + " " + unit; 186  } 187 
188     public Money() { 189         setMoney(0.0, null); 190  } 191 
192     public Money(double amount, String unit) { 193  setMoney(amount, unit); 194  } 195 
196     public Money(Money m) { 197  setMoney(m.amount, m.unit); 198  } 199 
200     public void setMoney(double amount, String unit) { 201         this.amount = amount; 202         this.unit = unit; 203  } 204 
205     public boolean equals(Object obj) { 206         Money other = (Money) obj; 207         return amount == other.amount 208             && unit.equals(other.unit); 209  } 210 }

 

4.2 调用最新的汇率信息

将在下次继续.

Date: 2014-05-05 Mon

Author: Zhong Xiewei

Org version 7.8.11 with Emacs version 24

Validate XHTML 1.0


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM