在教学实验中,为了演示一个企业在一定时期内某种产品的订单走势,需要模拟生成一定时期内的订单。教学老师生成一系列的订单,需要选择产品、客户、订单的开始日期和结束日期,再选择一种算法。系统根据算法的预先配置,生成一系列的订单。
       综合考虑以上的需求,产生订单的过程是由开始和结束日期确定产生的订单的个数,在数学的坐标中表现为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 getFormulagetEquationgeneratesetParams方法用于向类设置一个HashMap,其中包含了所有公式需要的参数,比如对于y=a*x+b,需要有a=200,b=20,offset=10GetFormula的作用是返回一个字符串,字符串的值为当前使用的公式,例y=a*x+b。在设置了参数setParams之后,具体的实现类就可以根据参数来形成具体的方程式,即getEquation方法,例:y=200x+20 offset=20Generate方法是整个算法的核心实现部分,需要传入字符形式的开始日期和结束日期。2.定义一个抽象类AbstractGenerator,实现IDataGenerator接口,包含一些通用的方法,定义formulaequationparam变量,同时添加他们的getset方法。由于子类中需要从Param中获取变量,因此在抽象类中增加了getDblValueFromParamsgetIntValueFromParams方法。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 接口便可以使用,使得程序的扩展变得相当容易。具有良好的可扩展性。文档的注释也比较全,需要源代码的同仁请自己下载,有不明白的地方或者有可以进一步改进的部分请联系本人。