简单工厂
2008-07-01 16:16 Henry Cui 阅读(1846) 评论(5) 编辑 收藏 举报
简单的工厂我的理解就是根据具体的情况,返回一个类型的具体类。一般时简单的工厂由:工厂、抽象产品、具体产品组成:
1.抽象产品:定义了具体产品公共的特性。可以是一个abstract calss 或者一个 interface;
2.具体产品:定义了工厂Create出来的具体产品。一般是一个具体实现的类继承与抽象产品;
3.工 厂:客户端调用,用来根据不同的情况产生不同的产品。
看一个现实中的例子:
在一般的软件公司,里面一般有实习生跟正式员工之分,而两者都是employee,有他们共同的特性如:姓名、工作的年限、工资等。而实习生跟正式员工的工资计算一般是不一样的,比如说:实习生的工资不管你做多少年都是2000/m,而正式员工的工资是:3000+500*工作年限/m。
从上面的实例可以看出employee里面有两个产品:Intern(实习生)、Official(正式员工)。所以我们先来设计一个抽象产品(Employee)跟两个具体产品(Intern、Offical):
抽象的Employee我用的是抽象的类来实现的,并没有用接口,因为他们有公用的字段(_firstName、_lastName、_workYears),用接口来实现在子类继承时比较麻烦点,都重新要定义字段。
Employee.cs:
Intern.cs:
Official.cs:
然后我们建立Factory来实现各种类型的员工的创建:
上面的Factory在理论上是没有问题,可是我们发现如果我们现在添加一种“退休”员工呢?这种方法是肯定不行的。比较好的解决办法就是将要创建的类型写在配置文件中。
1.抽象产品:定义了具体产品公共的特性。可以是一个abstract calss 或者一个 interface;
2.具体产品:定义了工厂Create出来的具体产品。一般是一个具体实现的类继承与抽象产品;
3.工 厂:客户端调用,用来根据不同的情况产生不同的产品。
看一个现实中的例子:
在一般的软件公司,里面一般有实习生跟正式员工之分,而两者都是employee,有他们共同的特性如:姓名、工作的年限、工资等。而实习生跟正式员工的工资计算一般是不一样的,比如说:实习生的工资不管你做多少年都是2000/m,而正式员工的工资是:3000+500*工作年限/m。
从上面的实例可以看出employee里面有两个产品:Intern(实习生)、Official(正式员工)。所以我们先来设计一个抽象产品(Employee)跟两个具体产品(Intern、Offical):
抽象的Employee我用的是抽象的类来实现的,并没有用接口,因为他们有公用的字段(_firstName、_lastName、_workYears),用接口来实现在子类继承时比较麻烦点,都重新要定义字段。
Employee.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleFactory
{
public abstract class Employee
{
Files And Attributes
Methods
}
}
using System.Collections.Generic;
using System.Text;
namespace SimpleFactory
{
public abstract class Employee
{
Files And Attributes
Methods
}
}
Intern.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleFactory
{
public class Intern:Employee
{
/// <summary>
/// 工资
/// </summary>
public override double Salary
{
get
{
return 2000.00;
}
}
Methods
}
}
using System.Collections.Generic;
using System.Text;
namespace SimpleFactory
{
public class Intern:Employee
{
/// <summary>
/// 工资
/// </summary>
public override double Salary
{
get
{
return 2000.00;
}
}
Methods
}
}
Official.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleFactory
{
public class Official:Employee
{
/// <summary>
/// 工资
/// </summary>
public override double Salary
{
get
{
return 3000 + 500 * this.WorkYears;
}
}
Methods
}
}
using System.Collections.Generic;
using System.Text;
namespace SimpleFactory
{
public class Official:Employee
{
/// <summary>
/// 工资
/// </summary>
public override double Salary
{
get
{
return 3000 + 500 * this.WorkYears;
}
}
Methods
}
}
然后我们建立Factory来实现各种类型的员工的创建:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Configuration;
namespace SimpleFactory
{
public class EmployeeFactory
{
/// <summary>
/// 创建一个员工对象
/// </summary>
/// <param name="employeeType">员工类型</param>
public Employee Creat(string employeeType,string fName,string lName,int years)
{
if(employeeType=="Intern")
{
return new Inter(fName,lName,years);
}
if(employeeType=="Official")
{
return new Official(fName,lName,years);
}
return null;
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Configuration;
namespace SimpleFactory
{
public class EmployeeFactory
{
/// <summary>
/// 创建一个员工对象
/// </summary>
/// <param name="employeeType">员工类型</param>
public Employee Creat(string employeeType,string fName,string lName,int years)
{
if(employeeType=="Intern")
{
return new Inter(fName,lName,years);
}
if(employeeType=="Official")
{
return new Official(fName,lName,years);
}
return null;
}
}
}
上面的Factory在理论上是没有问题,可是我们发现如果我们现在添加一种“退休”员工呢?这种方法是肯定不行的。比较好的解决办法就是将要创建的类型写在配置文件中。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="employeeType" value="SimpleFactory.Official"/>
</appSettings>
</configuration>
然后我们通过反射机制来实现创建:<configuration>
<appSettings>
<add key="employeeType" value="SimpleFactory.Official"/>
</appSettings>
</configuration>
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Configuration;
namespace SimpleFactory
{
public class EmployeeFactory
{
/**//// <summary>
/// 创建一个员工对象
/// </summary>
public Employee Creat(string fName,string lName,int years)
{
string employeeType = ConfigurationSettings.AppSettings["employeeType"];
if(employeeType!=null)
{
object[] parms = new object[] {fName,lName,years};//初始化的参数
return (Employee) Activator.CreateInstance(Type.GetType(employeeType),parms);
}
return null;
}
}
}
在客户端:using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Configuration;
namespace SimpleFactory
{
public class EmployeeFactory
{
/**//// <summary>
/// 创建一个员工对象
/// </summary>
public Employee Creat(string fName,string lName,int years)
{
string employeeType = ConfigurationSettings.AppSettings["employeeType"];
if(employeeType!=null)
{
object[] parms = new object[] {fName,lName,years};//初始化的参数
return (Employee) Activator.CreateInstance(Type.GetType(employeeType),parms);
}
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleFactory;
using System.Configuration;
namespace ClientOfFactory
{
class Program
{
static void Main(string[] args)
{
EmployeeFactory ef = new EmployeeFactory();
Employee em = ef.Creat("Henllyee","Cui",1);
if (em != null)
{
Console.Write(em.ShowInfo() + "\n");
}
else
{
Console.Write("创建对象出错,请查看配置文件!");
}
Console.Write("----------------------------\n");
Console.Read();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleFactory;
using System.Configuration;
namespace ClientOfFactory
{
class Program
{
static void Main(string[] args)
{
EmployeeFactory ef = new EmployeeFactory();
Employee em = ef.Creat("Henllyee","Cui",1);
if (em != null)
{
Console.Write(em.ShowInfo() + "\n");
}
else
{
Console.Write("创建对象出错,请查看配置文件!");
}
Console.Write("----------------------------\n");
Console.Read();
}
}
}
这样我们就可以通过修改配置文件来创建不同的具体产品。
文件下载地址:https://files.cnblogs.com/henllyee/DesinModule.rar