[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
posted @ 2014-05-06 16:01  grassofsky  阅读(5098)  评论(0编辑  收藏  举报