构建简单工厂
现在很容易给出简单工厂类。只检测逗号是否存在,然后返回其中的一个类的实例。
public class NameFactory
{public NameFactory(){}public Namer getName(string name){int i=name.IndexOf(",");if(i>0)return new LastFirst(name);else{return new FirstFirst(name);}}
}
使用工厂
接下来看看怎样把上述部分组合在一起。为了响应Compute把按钮单击事件,用一个NameFactory
实例返回正确的派生类。
private void btCompute_click(object sender,System.EventArgs e)
{Namer nm=nameFact.getName(txName.Text);txFirst.Text=nm.getFrname();txLast.Text=nm.getLname();
}
然后调用get重方法和getLname方法获得正确拆分的名字。这里不需要知道使用的是哪一
个派生类,工厂为我们提供了这个类,所需要知道的就是它有两个取出()方法。
我们构建了一个简单用户接口,允许用户以两种方式输入名字,然后显示拆分后的名字。
输入一个名字,然后单击Compute按钮,拆分后的名字显示在下面的文本域中。该程序的关键
之处在于Compute方法,它取回输入的文本,获得Namer类的实例,然后显示结果。
这就是简单工厂模式的基本原理。创建了一个抽象工厂,它决定返回哪一个类的实例并将该实
例返回。接下来可以调用那个类实例的方法,但不需要知道具体使用的是哪一个子类,这种方法把
和数据相关的问题与类的其他方法分隔开来。
数学计算中的工厂模式
大多数使用工厂模式的人都认为,工厂模式可以作为简化杂乱的编程类的工具。然而,工厂模
式用在执行数学运算的程序里也是非常合适的。例如,在快速傅里叶变换(FFT)中,下列四个方
程式要对大量的点对重复执午多遍,才能完成转换。根据这些计算结果绘制的图形形状,将下面
匹个方程式组成FFT“Butterfly(蝴蝶)"类的一个实例。四个方程式如下所示:
R1′=R1+R2cos(y)−I2sin(y)R_{1}' = R_{1} + R_{2}\cos(y) - I_{2}\sin(y)R1′=R1+R2cos(y)−I2sin(y) (1)
R2′=R1−R2cos(y)+I2sin(y)R_{2}' = R_{1} - R_{2}\cos(y) + I_{2}\sin(y)R2′=R1−R2cos(y)+I2sin(y) (2)
I1′=I1+R2sin(y)+I2cos(y)I_{1}' = I_{1} + R_{2}\sin(y) + I_{2}\cos(y)I1′=I1+R2sin(y)+I2cos(y) (3)
I2′=I1−R2sin(y)−I2cos(y)I_{2}' = I_{1} - R_{2}\sin(y) - I_{2}\cos(y)I2′=I1−R2sin(y)−I2cos(y) (4)
当角度y为零时,每次遍历数据时,仍然需要多次计算。这种情况下,可将复杂的数学计算
简化为公式(5)~(8):
R1′=R1+R2R_{1}' = R_{1} + R_{2}R1′=R1+R2 (5)
R2′=R1−R2R_{2}' = R_{1} - R_{2}R2′=R1−R2 (6)
I1′=I1+I2I_{1}' = I_{1} + I_{2}I1′=I1+I2 (7)
I2′=I1−I2I_{2}' = I_{1} - I_{2}I2′=I1−I2 (8)
我们先定义一个保存复数的类。
public class Complex
{float real;float imag;public Complex(float r,float i){real=r;imag=i;}public void setReal(flaot r){real=r;}public void setImag(float i){imag=i;}public float getReal(){return real;}public float getImag(){return imag;}
}
基类Butterfly是一个抽象类,任何一个具体类都要填充Execute命令的实现过程。
public abstract class Bufferfly
{float y;public Bufferfly(){public Bufferfly(float angle){y=angle;}abstract public void Execute(Complex X,Complex y);}
}
接下来在Butty的基础上创建一个简单的加法类,它实现了公式(5~8)的加法和减法运算
class AddBufferfly:AddBufferfly
{float oldr1,old2;public AddBufferfly(float angle){public override void Execute(Complex xi,Complex xj){oldr1=xi.getReal();oldi1=xi.getImag();xi.setReal(oldr1+xj.getReal());xj.setReal(oldr1- xj.getReal());xi.setImag(oldi1+xj.getImag());xj.setImag(oldi1-xj.getImag());}}
}
TrigButterny类与此类似,只是Execute方法包含了公式(1)、(4)中的三角函数的计算
public class TrigButterfly:TrigButterfly{float y,oldr1,oldi1;float cosy,siny;float r2cosy,r2siny,i2cosy,i2siny;}public TrigButterfly(float angle){y=angle;cosy=(float)Math.Cos(y);siny=(float)Math.Sin(y);}public override void Execute(Complex xi,Complex xj){oldr1=xi.getReal();oldi1=xi.getImag();r2cosy=xj.getReal()*cosy;r2siny=xj.getReal()*siny;i2cosy=xj.getImag()*cosy;i2siny=xj.getImag()*siny;xi.setReal(oldr1+r2cosy+i2siny);xi.setImag(oldi1-r2siny+i2cosy2);xj.setReal(oldr1-r2cosy-i2siny);xj.setImag(oldi1+r2siny-i2cosy);}
然后创建一个简单工厂类,它决定返回哪一个类实例。因为已经创建了类,所以,我
们把T厂类称为Cocoon(茧)。这里不需要实例化Cocoon,所以将它的方法声明为静态的。
public class Cocoon
{static public Butterfly getButterfly(float y){if(y!=0)return new TrigButterfly(y);elsereturn new addButterfly(y);}
}