我们来看一个类图。
图中,我们可以看到,客户需要得到某系列的产品的时候,直接用相应的工厂子类来创建产品就可以了。
示例用例图
接来下我们设计个邮件发送的线程实例,先看用例图:
代码设计
首先创建一个接口ISaaSProcess.cs:
/// <summary>
/// 异步调用接口
/// </summary>
public interface ISaaSProcess
{
/// <summary>
/// 启动线程任务
/// </summary>
void StartProcess();
/// <summary>
/// 停止线程任务
/// </summary>
void StopProcess();
/// <summary>
/// 显示结果
/// </summary>
/// <returns></returns>
List<string> GetResult();
}
然后创建一个工厂基类SaaSProcessBase.cs:
public abstract class SaaSProcessBase : ISaaSProcess
{
/// <summary>
/// 记录Log内容
/// </summary>
public List<string> _logContent = new List<string>();
public SaaSProcessBase()
{
}
#region ISaaSProcess Members
public void StartProcess()
{
try
{
InitialProcess();
if (CheckCondition())
{
DoProcess();
EndProcess();
ClearProcess();
}
else
{
_logContent.Add("条件检测不通过,不能正常启动");
}
}
catch (Exception ex)
{
_logContent.Add("任务的某个线程执行过程中出现异常" + ex.Message);
}
}
public void StopProcess()
{
SetLastUpdateTime(DateTime.Now);
}
public List<string> GetResult()
{
return _logContent;
}
/// <summary>
/// 记录最后操作时间
/// </summary>
/// <param name="time"></param>
public void SetLastUpdateTime(DateTime time)
{
_logContent.Add("线程结束时间是" + time.ToString());
}
#endregion
#region abstract method
/// <summary>
/// 检查条件是否符合
/// </summary>
/// <returns></returns>
public abstract bool CheckCondition();
/// <summary>
/// 初始化线程
/// </summary>
public abstract void InitialProcess();
/// <summary>
/// 执行线程任务
/// </summary>
public abstract void DoProcess();
/// <summary>
/// 结束线程任务
/// </summary>
public abstract void EndProcess();
/// <summary>
/// 清理线程
/// </summary>
public abstract void ClearProcess();
#endregion
}
然后创建一个发送邮件的工厂EmailEngine.cs:
public class EmailEngine : SaaSProcessBase
{
public override bool CheckCondition()
{
return true;
}
public override void InitialProcess()
{
_logContent.Add("所有数据准备完毕");
}
public override void DoProcess()
{
_logContent.Add("邮件发送成功");
}
public override void EndProcess()
{
_logContent.Add("邮件发送结束");
}
public override void ClearProcess()
{
_logContent.Add("邮件数据清理完毕");
}
public EmailEngine()
{ }
}
然后再调用它:
public partial class Run : Form
{
public Run()
{
InitializeComponent();
}
private void btnRun_Click(object sender, EventArgs e)
{
ISaaSProcess process = new EmailEngine();
process.StartProcess();
process.StopProcess();
foreach (string result in process.GetResult())
{
rtbResult.AppendText(result + "\n");
}
}
}
运行的结果如下图:
工厂子类不一定需要实现父类的所有方法,但要使子类有用的话,我们必须使它的所有方法宣布具体化。这里,就引出几种做法:1、工厂父类可以就是一个接口,以确保其 子类一定是具体的;2、我们可以继承抽象的父类,但不完全具体化,这样可以继续细分工厂子类;3、抽象的父类中含有具体的方法,这些方法也可以不加virtual修饰符。最后的这种方法可能是比较灵活一点的。
抽象工厂主要是用在需要一系列相关联的类协同工作的地方,而且这些系列的数量可能会变多,每一个系列完成的工作都不一样,但是调用接口却是一样的。另外,抽象工厂不适合这样一种情况,即每个系列内部的元素数量不能够确定,也就是说,当初设计的时候,系列中有3个配件,后面又涨成5个,之后又涨到7个,这样的话,要改动的地方将多到让人受不了。
欢迎拍砖.