好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

步步为营 .NET 设计模式学习笔记 二、Abstract Factory(抽象工厂)

步步为营 .NET 设计模式学习笔记 二、Abstract Factory(抽象工厂)

抽象工厂模式是一种创建型的模式。上面的比喻说明了抽象工厂就是生产同一个系列产品的东西,因为这一系列的产品是关联的,如果混用就可能出问题,所以就统一的在抽象工厂中进行创建。当要增加一个新的产品系列时,就多写一个工厂子类并添加相应的产品子类就可以了。

我们来看一个类图。

    图中,我们可以看到,客户需要得到某系列的产品的时候,直接用相应的工厂子类来创建产品就可以了。

接来下我们设计个邮件发送的线程实例:

首先创建一个接口ISaaSProcess.cs:

view source print ?

/// <summary>

/// 异步调用接口

/// </summary>

public interface ISaaSProcess

{

     /// <summary>

     /// 启动线程任务

     /// </summary>

     void StartProcess();

     /// <summary>

     /// 停止线程任务

     /// </summary>

     void StopProcess();

     /// <summary>

     /// 显示结果

     /// </summary>

     /// <returns></returns>

     List< string > GetResult();

}

然后创建一个工厂基类SaaSProcessBase.cs:

view source print ?

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:

view source print ?

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()

        { }

    }

然后再调用它:

view source print ?

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个,这样的话,要改动的地方将多到让人受不了。

  欢迎拍砖.

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于步步为营 .NET 设计模式学习笔记 二、Abstract Factory(抽象工厂)的详细内容...

  阅读:40次