在教學實驗中,為了演示一個企業在一定時期內某種產品的訂單走勢,需要模擬生成一定時期內的訂單。教學老師生成一系列的訂單,需要選擇產品、客戶、訂單的開始日期和結束日期,再選擇一種演算法。系統根據演算法的預先配置,生成一系列的訂單。
綜合考慮以上的需求,產生訂單的過程是由開始和結束日期確定產生的訂單的個數,在數學的座標中表現為x軸上的整數點,對於每個x點產生相應的y值,這個y值就是訂單的產品數量。演算法的核心就是給出一個x值,求出對應的y值。計算y值需要一個公式,比如y=a*x+b,y=a*sin(b*x+c)+d,有了公式,還需要配置其中的引數,比如,a=100,b=0.3。有了引數,公式便可以成為方程式,此時給出一個x值便可以根據方程式求出相應的y值。在現實中的訂單並不可能嚴格根據方程式來生成的,因此有可能需要一定範圍內的偏差offset,即對於y值需要進行二次計算,在偏差的基礎上模擬出真實的資料。
基於以上的分析,做了以下的設計。1.定義一個介面,IDataGenerator,其中包括如下方法,setParams, getFormula,getEquation,generate。setParams方法用於向類設定一個HashMap,其中包含了所有公式需要的引數,比如對於y=a*x+b,需要有a=200,b=20,offset=10。GetFormula的作用是返回一個字串,字串的值為當前使用的公式,例y=a*x+b。在設定了引數setParams之後,具體的實現類就可以根據引數來形成具體的方程式,即getEquation方法,例:y=200x+20 offset=20。Generate方法是整個演算法的核心實現部分,需要傳入字元形式的開始日期和結束日期。2.定義一個抽象類AbstractGenerator,實現IDataGenerator介面,包含一些通用的方法,定義formula、equation、param變數,同時新增他們的get和set方法。由於子類中需要從Param中獲取變數,因此在抽象類中增加了getDblValueFromParams和getIntValueFromParams方法。Generator方法首先根據開始日期和結束日期計算出以天為單位兩個日期之間的時間間隔,也就是在座標的X軸上從0開始到結束點的座標,根據日期的長度定義一個二維陣列,陣列中儲存字串形式的日期和字串形式的整數。根據陣列的長度,迴圈計算每個日期對應的Y值,儲存在陣列中,最後返回陣列。因此Abstract的子類需要根據演算法計算出Y值,y值的計算方法需要根據相應得方程式得到,因此有一個需要被子類實現的抽象方法computeY()。由得到的y值根據生成的offset就生成的最終得y值,預設的curOffset()函式返回值為0,如果需要重新定義偏移量,可以在具體實現類中重新定義。3.定義具體的實現類,由於抽象類做了大量的工作,具體的實現類就變得相當簡單,以LineGenerator為例子,在預設建構函式中設定公式,繼承實現getEquation,返回具體的方程式。實現computeY()方法,在呼叫computeY()方法和getEquation()之前需要檢查引數是否設定,computeY()方法很簡單
public int computeY(long curX) {
initParams();
long result = Math.round(a *curX + b);
return new Integer(String.valueOf(result)).intValue();
}
計算偏移量的方法也比較簡單
protected int curOffset(){
Random rmd=new Random();
return rmd.nextInt(2*offset)-offset;
}
引數a、b、offset在初始化引數的過程中賦值。
函式的使用方法如下:
private HashMap params;
startDate = “2008-1-1 “;
endDate = “2008-2-1 “;
params = new HashMap();
params.put(“a”, “200”);
params.put(“b”, “0.3”);
params.put(“c”, “0”);
params.put(“d”, “0”);
IDataGenerator generator = new LineGenerator();
generator.setParams(params);
String[][] result = generator.generate(startDate, endDate);
每增加一個新的演算法,只需要實現Abstract介面便可以使用,使得程式的擴充套件變得相當容易。具有良好的可擴充套件性。文件的註釋也比較全,需要原始碼的同仁請自己下載,有不明白的地方或者有可以進一步改進的部分請聯絡本人。