小菜与简单工厂模式,工厂模式,包括抽象工厂模式的结缘都源至于以前支持多数据库的学习过程.
现在就来回顾下该过程,回顾下工厂系列模式.希望能带给你不一样的感觉,不一样的体会.
因为回顾写太长了,所以就没有写.Net Framework框架源码中的模式了.下篇会都补上.
小菜前段时间写了一些梦游Discuz!NT2.0的文章,现在就以它为例来说明吧.
我们的工作是支持SqlServer数据库,Access数据库,MySql数据库.
这样的话,每一种对数据库的操作都会对应三种不同的实现.
以dnt_forums(论坛版块信息表)为例. 已有数据 (这个表被小菜简化了,因为这样更能说明问题)
| fid : 版块编号 | name : 版块名称 |
| 1 | 版块1 |
| 2 | 版块2 |
现在要求提供操作.
1.按fid访问数据库取出name ==> string GetForumName(int fid)
等等数据库相关操作......
先来看看代码的组织吧.
很直观.接下来就来看代码吧.
数据访问接口

Code
using System;
namespace Discuz.Data
{
public interface IForumManage
{
string GetForumName(int fid);
}
}SqlServer数据库实现

Code
using System;
using Discuz.Data;
namespace Discuz.Data.SqlServer
{
public class ForumManage : IForumManage
{
public string GetForumName(int fid)
{
//SqlServer数据库实现,具体实现略
return "SqlServer版块名称";
}
}
}大家不要骂小菜说骗人噢,假的实现, :) 因为这里是讲设计模式,不应该把太多的实现带进来.
如果想复习下数据库的操作,可参看 <小菜梦游Discuz!NT数据层设计部份>
Access数据库实现

Code
using System;
using Discuz.Data;
namespace Discuz.Data.Access
{
public class ForumManage : IForumManage
{
public string GetForumName(int fid)
{
//Access数据库实现,具体实现略
return "Access版块名称";
}
}
}
MySql数据库实现

Code
using System;
using Discuz.Data;
namespace Discuz.Data.MySql
{
public class ForumManage : IForumManage
{
public string GetForumName(int fid)
{
//MySql数据库实现,具体实现略
return "MySql版块名称";
}
}
}
这样的话,那么我们的客户程序便可以方便的使用了.
Default.aspx页面

Code
using System;
using Discuz.Data;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
IForumManage forumManage = null;
string dbType = "SqlServer"; //如果要使用其它数据库改这里 switch (dbType)
{
case "SqlServer":
forumManage = new Discuz.Data.SqlServer.ForumManage();
break;
case "Access":
forumManage = new Discuz.Data.Access.ForumManage();
break;
case "MySql":
forumManage = new Discuz.Data.MySql.ForumManage();
break;
default:
throw new Exception("暂时只支持SqlServer,Access,MySql");
}
Response.Write("版块名称:" + forumManage.GetForumName(1));
}
}
如果小菜想在页面Forum.aspx也使用ForumManage类,怎么办呢?
这还不简单:

Code
using System;
using Discuz.Data;
public partial class Forum : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
IForumManage forumManage = null;
string dbType = "SqlServer"; //如果要使用其它数据库改这里 switch (dbType)
{
case "SqlServer":
forumManage = new Discuz.Data.SqlServer.ForumManage();
break;
case "Access":
forumManage = new Discuz.Data.Access.ForumManage();
break;
case "MySql":
forumManage = new Discuz.Data.MySql.ForumManage();
break;
default:
throw new Exception("暂时只支持SqlServer,Access,MySql");
}
Response.Write("版块名称:" + forumManage.GetForumName(1));
//或者使用forumManage的其它方法
}
}
苍天啊,大地啊,怎么会这样啊,一模一样的代码竟然出现.(代码中有坏味道,看来我们得重构一下它才行)
怎么办呢? 把创建具体ForumManage的逻辑独立出来,放入某个类中,就设为ForumFactory吧
这样我们就引入ForumFactory类

Code
using System;
using Discuz.Data;
public class ForumFactory
{
public static IForumManage Create(string dbType)
{
IForumManage forumManage = null;
switch (dbType)
{
case "SqlServer":
forumManage = new Discuz.Data.SqlServer.ForumManage();
break;
case "Access":
forumManage = new Discuz.Data.Access.ForumManage();
break;
case "MySql":
forumManage = new Discuz.Data.MySql.ForumManage();
break;
default:
throw new Exception("暂时只支持SqlServer,Access,MySql");
}
return forumManage;
}
}那么,我们在Default.aspx和Forum.aspx等地方使用ForumManage将方便许多,不信就接着往下看.
Default.aspx页面

Code
using System;
using Discuz.Data;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
IForumManage forumManage = null;
forumManage = ForumFactory.Create("SqlServer");//如果要使用其它数据库改这里
Response.Write("版块名称:" + forumManage.GetForumName(1));
}
}