C# 简单工厂模式(构建简单工厂)

构建简单工厂

现在很容易给出简单工厂类。只检测逗号是否存在,然后返回其中的一个类的实例。

csharp 复制代码
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

实例返回正确的派生类。

csharp 复制代码
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)

我们先定义一个保存复数的类。

csharp 复制代码
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命令的实现过程。

csharp 复制代码
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)的加法和减法运算

csharp 复制代码
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)中的三角函数的计算

csharp 复制代码
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,所以将它的方法声明为静态的。

csharp 复制代码
public class Cocoon
{
    static public Butterfly getButterfly(float y)
    {
        if(y!=0)
            return new TrigButterfly(y);
        else
            return new addButterfly(y);
            
    }
}