简单工厂模式(Simple Factory Pattern)根据提供给它的参数,返回几个可能类中的一个类的实例。通常它返回的类都有一个共同的父类和共同的方法,但每个方法执行的任务不同,而且根据不同的参数进行了优化。简单工厂模式实际上不属于23个GoF模式,但它可以作为工厂方法模式的一个引导。
考虑一个简单的例子,在它里面用到了Factory 类。假设我们有一个输入窗体,允许用户输入他的姓名,可以是“firstname lastname”形式或“lastname,firstname”形式。现在进一步简化这个问题,假设我们总是能通过判断lastname和firstname之间是否有逗号来确定姓名的顺序。
我们这里用它说明工厂如何工作以及工厂能生成哪些对象。先定义一个简单的类,它用构造函数接收表示名字的字符串,并且可以从类中取回名字。
//Base class for getting split names
public class Namer
{
//parts stored here
protected string frName, lName;
//return first name
public string getFrname()
{
return frName;
}
![]()
//return last name
public string getLname()
{
return lName;
}
}
注意,在这个基类里没有设置名字的构造函数。
接下来编写两个非常简单的派生类,它们实现了接口,并在构造函数中将名字分成了两部分。
在FirstFisrt类中,做了一个简单的假设:最后一个空格前面的所有部分都属于firstname。
public class FirstFirst : Namer
{
public FirstFirst(string name)
{
int i = name.IndexOf (" ");
if(i > 0)
{
frName = name.Substring (0, i).Trim ();
lName = name.Substring (i + 1).Trim ();
}
else
{
lName = name;
frName = "";
}
}
}
在LastFirst类里.用逗号给lastname划分界限。当空格或逗号不存在时,两个类里都提供了错误校正处理。
public class LastFirst : Namer
{
public LastFirst(string name)
{
int i = name.IndexOf (",");
if(i > 0)
{
lName = name.Substring (0, i);
frName = name.Substring (i + 1).Trim ();
}
else
{
lName = name;
frName = "";
}
}
}
现在很容易给出简单工厂类。只检测逗号是否存在,然后返回其中的一个类的实例。
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);
}
}
}
接下来看看怎样把上述部分组合在一起。为了响应按钮单击事件,用—个NameFactory实例返回正确的派生类。
private void btCompute_Click(object sender, System.EventArgs e)
{
Namer nm = nameFact.getName (txName.Text );
txFirst.Text = nm.getFrname ();
txLast.Text = nm.getLname ();
}
然后调用getFrname方法和getLname方法获得正确拆分的名字。这里不需要知道使用的是哪一个派生类,工厂为我们提供了这个类,所需要知道的就是它有两个取出(get)方法。完整的类图如下图所示:
![]()
这就是简单工厂模式的基本原理。创建了—个抽象工厂,它决定返回哪一个类的实例并将该实例返回。接下来可以调用那个类实例的方法,但不需要知道具体使用的是哪一个子类,这种方法把和数据相关的问题与类的其他方法分隔开来。
考虑一个简单的例子,在它里面用到了Factory 类。假设我们有一个输入窗体,允许用户输入他的姓名,可以是“firstname lastname”形式或“lastname,firstname”形式。现在进一步简化这个问题,假设我们总是能通过判断lastname和firstname之间是否有逗号来确定姓名的顺序。
我们这里用它说明工厂如何工作以及工厂能生成哪些对象。先定义一个简单的类,它用构造函数接收表示名字的字符串,并且可以从类中取回名字。
//Base class for getting split names
public class Namer
{
//parts stored here
protected string frName, lName;
//return first name
public string getFrname()
{
return frName;
}
//return last name
public string getLname()
{
return lName;
}
}接下来编写两个非常简单的派生类,它们实现了接口,并在构造函数中将名字分成了两部分。
在FirstFisrt类中,做了一个简单的假设:最后一个空格前面的所有部分都属于firstname。
public class FirstFirst : Namer
{
public FirstFirst(string name)
{
int i = name.IndexOf (" ");
if(i > 0)
{
frName = name.Substring (0, i).Trim ();
lName = name.Substring (i + 1).Trim ();
}
else
{
lName = name;
frName = "";
}
}
}在LastFirst类里.用逗号给lastname划分界限。当空格或逗号不存在时,两个类里都提供了错误校正处理。
public class LastFirst : Namer
{
public LastFirst(string name)
{
int i = name.IndexOf (",");
if(i > 0)
{
lName = name.Substring (0, i);
frName = name.Substring (i + 1).Trim ();
}
else
{
lName = name;
frName = "";
}
}
}现在很容易给出简单工厂类。只检测逗号是否存在,然后返回其中的一个类的实例。
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);
}
}
}接下来看看怎样把上述部分组合在一起。为了响应按钮单击事件,用—个NameFactory实例返回正确的派生类。
private void btCompute_Click(object sender, System.EventArgs e)
{
Namer nm = nameFact.getName (txName.Text );
txFirst.Text = nm.getFrname ();
txLast.Text = nm.getLname ();
}这就是简单工厂模式的基本原理。创建了—个抽象工厂,它决定返回哪一个类的实例并将该实例返回。接下来可以调用那个类实例的方法,但不需要知道具体使用的是哪一个子类,这种方法把和数据相关的问题与类的其他方法分隔开来。

浙公网安备 33010602011771号