新手学抽象工厂模式(AbstractFactory)
前言:最近朋 友辞职下海做网络购物方面,让我帮点忙,地球人都知道在中国搞程序的口袋里银子没有几两,也只能提供所谓技术支持了,于是就把购物网网站的活接了下来。朋友申请的空间竟然只支持Access数据库。同时他还要求网站的数据库以后要 移植到Sql Server。这样问题来了,如果更换数据库则要更改大量代码。同时我也有私心要把这个网站做成一个网站模板方便我以后有类似的活可以直接套用。以后说不 准这个客户要求Access,那个客户要求Sql Server, 或Oracle了,那我更改代码的工作量就也太大了,同时维护起来也极为不方便。试想维护三、四个功能相同又不太一样的系统是多么痛苦的事情。难道就不能 够换数据库的时候不用更改代码吗?答案是肯定的,
实例:用户登录,为了阐述简单数据库操作只设计一个方法CheckUser(string userName, string pwd)
案例分析:为了数据库可移植性,必须做到系统一旦发布就不用更改源代码,只需要更正相应的webConfig文件就能够动态的链接正确的数据库。项目接口定义如下:IDAL用于定义数据库方法接口,IFactory工厂方法接口定义,
物理模型:同样为了简单这里只涉及SqlServer,Access数据库
项目对应方法:
项目 |
包含的类 |
IFactory |
IFactoryLogin |
AccessFactroy |
AccessFactoryLogin |
SqlServerFactory |
SqlServerFactoryLogin |
IDAL |
IDalLogin |
AccessDal |
AccessDalLogin |
SqlServerDal |
SqlServerDalLogin |
BLL |
MakeFactory |
类别 |
方法/接口 |
IFactory |
public interface IFactoryLogin{IDAL.IDALLogin IFactoryCheckUser()} |
AccessFactoty |
public IDAL.IDALLogin IFactoryCheckUser() |
SqlServerFactory |
public IDAL.IDALLogin IFactoryCheckUser() |
IDAL |
bool IDALCheckUse(string userName) |
AccessDal |
public bool IDALCheckUse(string userName) |
SqlServerDal |
public bool IDALCheckUse(string userName) |
BLL |
public IFactory.IFactoryLogin MakeFactoryUser() |
Web Config配置:
<appSettings>
<add key="IFactory" value ="SqlServerFactory"/>
</appSettings>
各方法详细:
namespace IFactory
{
public interface IFactoryLogin
{
IDAL.IDALLogin IFactoryCheckUserName();
}
}
该方法定义了IDAL的工厂接口,这样具体调用的时候就不用考虑具体实例化那个对象
namespace AccessFactory
{
public class AccessFactoryLogin:IFactory.IFactoryLogin
{
public IDAL.IDALLogin IFactoryCheckUserName()
{
return new AccessDal.AccessDalLogin();
}
}
}
该类实现IFactory接口返回IDAL.IDALLogin接口的一个实例
namespace SqlServerFactory
{
public class SqlServerFactoryLogin:IFactory.IFactoryLogin
{
public IDAL.IDALLogin IFactoryCheckUserName()
{
return new SqlServerDal.SqlServerDalLogin();
}
}
}
同上
namespace IDAL
{
public interface IDALLogin
{
bool IDALCheckUseName(string userName);
}
}
定义数据连接层公共接口
namespace SqlServerDal
{
public class SqlServerDalLogin:IDAL.IDALLogin
{
string strConnection = ConfigurationManager.ConnectionStrings["SqlConnectionString"].ConnectionString;
public bool IDALCheckUseName(string userName)
{
bool result = false;
string strSql = "SELECT COUNT(*) FROM MyUser WHERE UserName=@userName";
SqlConnection conn = new SqlConnection(strConnection);
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(strSql, conn);
SqlParameter para = new SqlParameter("@userName", userName);
cmd.Parameters.Add(para);
int i = Convert.ToInt32(cmd.ExecuteScalar());
if (i > 0)
{
result = true;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
}
return result;
}
}
}
实现IDAL.IDALLogin接口
namespace BLL
{
public class MakeFactory
{
string factoryName = ConfigurationManager.AppSettings["IFactory"];
IFactory.IFactoryLogin ifactory = null;
public IFactory.IFactoryLogin MakeFactoryLogin()
{
switch (factoryName)
{
case "SqlServerFactory":
ifactory = new SqlServerFactory.SqlServerFactoryLogin();
break;
case "AccessFactory":
ifactory = new AccessFactory.AccessFactoryLogin();
break;
}
return ifactory;
}
}
}
根据配置文件动态链接不同数据库
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
BLL.MakeFactory bllMakeFactory = new BLL.MakeFactory();
IFactory.IFactoryLogin ifactory = bllMakeFactory.MakeFactoryLogin();
bool boo = ifactory.IFactoryCheckUserName().IDALCheckUseName(TextBox1.Text);
}
}
页面方法调用。
本来想写多一些的,太烦了算了,自己看懂就行