[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