“抽象工厂模式”三层架构方法的实现_2581
策略模式简单工厂模式抽象工厂模式
策略模式简单工厂模式抽象工厂模式策略模式、简单工厂模式和抽象工厂模式是常见的设计模式,用于解决不同的问题和满足不同的设计需求。
下面将分别介绍这三种模式,并进行详细的比较。
策略模式策略模式是一种行为型模式,它将一组特定的算法封装成一个独立的类,使得它们可以相互替换。
应用策略模式的主要目的是让算法的变化独立于使用算法的客户端。
策略模式将算法的定义与算法的使用分离开来,这样可以让算法的定义更加灵活,能够根据需要动态地改变。
简单工厂模式简单工厂模式是一种创建型模式,它由一个工厂类负责创建不同类型的对象。
简单工厂模式的核心思想是将对象的创建过程封装起来,客户端只需要通过一个工厂类的方法来获取所需的对象,而不需要了解创建对象的细节。
简单工厂模式常常使用静态方法来创建对象,这样客户端可以直接通过类名来调用工厂方法。
抽象工厂模式也是一种创建型模式,它提供了一种创建一族相关或相互依赖对象的接口,而不需要指定具体的类。
抽象工厂模式的核心思想是将对象的创建过程封装到一个工厂接口中,具体的工厂类实现这个接口来创建不同的对象。
抽象工厂模式可以用于创建一系列的产品对象,这些产品对象有一定的关联关系。
比较1.目的不同:-策略模式的目的是将一组算法封装起来,使得它们可以相互替换。
-简单工厂模式的目的是封装对象的创建过程,使得客户端只需要通过一个工厂类的方法来获取所需的对象。
-抽象工厂模式的目的是提供一种创建一族相关或相互依赖对象的接口。
2.使用场景不同:-策略模式适用于一组特定的算法需要进行动态切换或扩展的场景。
-简单工厂模式适用于需要根据输入参数来决定创建具体对象的场景。
-抽象工厂模式适用于需要创建一系列相关或相互依赖的对象的场景。
3.灵活性不同:-策略模式的算法可以灵活地添加、删除或替换,客户端可以根据需要动态地选择所需的算法。
-简单工厂模式的创建过程在工厂类中,所以客户端只能通过修改工厂类代码来实现创建对象的变化,不够灵活。
软件开发模式——三层抽象工厂模式DOCX
beniao.blog.51cto./389148/102304.cnblogs./jingyun/archive/2010/04/16/1713341.html实现步骤过程1、创建Model,实现业务实体。
2、创建IDAL,实现接口。
3、创建SQLServerDAL,实现接口里的方法。
4、增加web.config里的配置信息,为SQLServerDAL的程序集。
5、创建DALFactory,返回程序集的指定类的实例。
6、创建BLL,调用DALFactory,得到程序集指定类的实例,完成数据操作方法。
7、创建WEB,调用BLL里的数据操作方法。
注意:1、web.config里的程序集名称必须与SQLServerDAL里的输出程序集名称一致。
2、DALFactory里只需要一个DataAccess类,可以完成创建所有的程序集实例。
3、项目创建后,注意修改各项目的默认命名空间和程序集名称。
4、注意修改解决方案里的项目依赖。
5、注意在解决方案里增加各项目引用。
三、各层间的访问过程1、传入值,将值进行类型转换(为整型)。
2、创建BLL层的content.cs对象c,通过对象c访问BLL层的方法GetContentInfo(ID)调用BLL层。
3、BLL层方法GetContentInfo(ID)中取得数据访问层SQLServerDAL的实例,实例化IDAL层的接口对象dal,这个对象是由工厂层DALFactory创建的,然后返回IDAL层传入值所查找的容的方法dal.GetContentInfo(id)。
4、数据工厂通过web.config配置文件中给定的webdal字串访问SQLServerDAL层,返回一个完整的调用SQLServerDAL层的路径给BLL层5、到此要调用SQLServerDAL层,SQLServerDAL层完成赋值Model层的对象值为空,给定一个参数,调用SQLServerDAL层的SqlHelper的ExecuteReader方法,读出每个字段的数据赋值给以定义为空的Model层的对象。
讲解三层结构和抽象工厂模式教程
讲解三层结构和抽象工厂模式这里我们结合课件,采用案例演示教学法,层层深入,大把这个难点讲解完成。
前面课程已经讲解简单三层授课技巧,后续任务在此基础上实现。
操作流程:1.添加一个新的项目(类库):AccessDAL。
2.修改原先的DAL层名称为SQLDAL,并修改所有的该层命名空间为SQLDAL.并修改此项目的属性的程序集名称和默认命名空间名称为SQLDAL。
3.修改BLL层所有相关DAL层的引用。
using SQLDAL4.编译项目,重新生成。
接口的引入和简单工厂:为什么要使用接口呢,现在的软件产品不可能指针对一个数据库,如劳资管理系统,大公司使用SQL Server,小公司可能使用access就够用了,那么如何让一套程序既可使用SQL Server又可使用Access作为数据库呢,答案是我们在数据访问层使用统一的接口,让访问SQL Server和Access的类都实现这个接口,然后通过接口调用具体的实现。
具体的演示方法是在前面代码的基础上点击DAL层的类,右键选择重构,选择提取接口,这样一个接口就出现了。
如下图所示:图三提取接口我们这里为了更加的规范,建立一个接口层的类库IDAL,将这个接口移到这个类库IDAL 中,要注意删除原有在SQLDAL中的接口。
重新编译,修改错误。
修改原先引用接口的代码:IDAL.IGuestService在数据访问层添加对IDAL的引用,并增加using IDAL代码。
同时调整拷贝到IDAL层的接口相关的代码,修改其命名空间。
namespace IDAL。
在业务逻辑层增加对IDAL的引用。
在IDAL添加对Models的引用。
接口建立以后,为了可以使用Access库,我们添加新的数据层AccessDAL,再添加一个GuestService类(注意必须和原有的Sqldal层类同名)并实现现刚刚创建的接口。
为了方便演示有一个技巧,你可以复制上面的代码到AccessDAL类库中,并做对应修改,返回值为空或true即可。
Python—程序设计:抽象工厂模式
Python—程序设计:抽象⼯⼚模式抽象⼯⼚模式内容:定义⼀个⼯⼚类接⼝,让⼯⼚⼦类来创建⼀系列相关或相互依赖的对象。
例:⽣产⼀部⼿机,需要⼿机壳、CPU、操作系统三类对象进⾏组装,其中每类对象都有不同的种类。
对每个具体⼯⼚,分别⽣产⼀部⼿机所需要的三个对象。
相⽐⼯⼚⽅法模式,抽象⼯⼚模式中的每个具体⼯⼚都⽣产⼀套产品。
⾓⾊:抽象⼯⼚⾓⾊(Creator)具体⼯⼚⾓⾊(Concrete Creator)抽象产品⾓⾊(Product)具体产品⾓⾊(Concrete Product)客户端(Client)优点:将客户端与类的具体实现相分离每个⼯⼚创建了⼀个完整的产品系列,使得易于交换产品系列有利于产品的⼀致性(即产品之间的约束关系)缺点: 难以⽀持新种类的(抽象)产品from abc import abstractmethod, ABCMeta# ------抽象产品------class PhoneShell(metaclass=ABCMeta):@abstractmethoddef show_shell(self):passclass CPU(metaclass=ABCMeta):@abstractmethoddef show_cpu(self):passclass OS(metaclass=ABCMeta):@abstractmethoddef show_os(self):pass# ------抽象⼯⼚------class PhoneFactory(metaclass=ABCMeta):@abstractmethoddef make_shell(self):pass@abstractmethoddef make_cpu(self):pass@abstractmethoddef make_os(self):pass# ------具体产品------class SmallShell(PhoneShell):def show_shell(self):print("普通⼿机⼩⼿机壳")class BigShell(PhoneShell):def show_shell(self):print("普通⼿机⼤⼿机壳")class AppleShell(PhoneShell):def show_shell(self):print("苹果⼿机壳")class SnapDragonCPU(CPU):def show_cpu(self):print("骁龙CPU")class MediaTekCPU(CPU):def show_cpu(self):print("联发科CPU")class AppleCPU(CPU):def show_cpu(self):print("苹果CPU")class Android(OS):def show_os(self):print("Android系统")class IOS(OS):def show_os(self):print("iOS系统")# ------具体⼯⼚------class MiFactory(PhoneFactory):def make_cpu(self):return SnapDragonCPU()def make_os(self):return Android()def make_shell(self):return BigShell()class HuaweiFactory(PhoneFactory): def make_cpu(self):return MediaTekCPU()def make_os(self):return Android()def make_shell(self):return SmallShell()class IPhoneFactory(PhoneFactory): def make_cpu(self):return AppleCPU()def make_os(self):return IOS()def make_shell(self):return AppleShell()# ------客户端------class Phone:def__init__(self, cpu, os, shell): self.cpu = cpuself.os = osself.shell = shelldef show_info(self):print("⼿机信息:")self.cpu.show_cpu()self.os.show_os()self.shell.show_shell()def make_phone(factory):cpu = factory.make_cpu()os = factory.make_os()shell = factory.make_shell() return Phone(cpu, os, shell)p1 = make_phone(IPhoneFactory()) p1.show_info()。
1、工厂三层模式操作步骤
工厂三层结构一、创建项目1、创建Model,实现业务实体。
2、创建IDAL,实现接口。
3、创建SQLServerDAL,实现接口里的方法。
4、创建DBUtility,放DBHelpersql.cs。
System.configuration5、创建DALFactory,返回程序集的指定类的实例。
放发的素材dataaccess.cs和datacache.cs System.Web、System.configurationDataaccess.cs 注释掉出错的代码6、创建BLL,调用DALFactory,得到程序集指定类的实例,完成数据操作方法。
7、创建WEB,调用BLL里的数据操作方法。
添加app-code文件夹,加入messagebox.Cs,修改属性里将生成操作的值内容改为编译二、添加引用1.在WEB层添加对BLL层、Model层、SQLServerDAL的引用2.在BLL层添加对SQLServerDAL(反射必须)、DALFactory、IDAL、Model层的引用3.在SQLServerDAL层添加对DBUtility、IDAL、Model层的引用4.在DALFactory层添加对IDAL层、System.Web、System.configuration的引用。
右键引用System。
web引用。
5.在IDAL层添加对Model层的引用三、修改配置文件1、修改web。
config中的<addkey="DAL"value="SQLServerDAL"/>节为自己的命名空间。
<appSettings><add key="DAL"value="SQLServerDAL"/></appSettings>2、修改webconfig添加连接字符串<connectionStrings><add name="sqlservercon"connectionString="user id=sa;password=sasasa;initial catalog=school;data source=.\SQLserver"providerName="System.Data.SqlClient" /></connectionStrings>web。
三层结构实现抽象工厂示例
连接数据库需要配置We b.config的Sql server,WebDAL节点是需要生成抽象工厂的实例,本登陆用到了3层结构+反射抽象工厂,才疏学浅,请大家多多指教。
BLL类:usingSystem;usingSystem.Collec tions.Generi c;usingSystem.Text;usingLogind emo.IDAL;usingLogind emo.Model;usingLogind emo.DALFac tory;namesp ace Logind emo.BLL{public classLogin{//利用反射生成实例privat e static readon ly ILogin denglu = Logind emo.DALFac tory.DataAc cess.Create Login();//登陆public int denglu la(Logini nfo log){return denglu.Logini ng(log);}}}DALFac tory类:usingSystem;usingSystem.Collec tions.Generi c;usingSystem.Text;usingSystem.Config urati on;usingSystem.Reflec tion;namesp ace Logind emo.DALFac tory{//此类用于实现抽象工厂模式去创建从配置文件指定的数据访问层的实例public sealed classDataAc cess{privat e static readon ly string path = System.Config urati on.Config urati onMan ager.AppSet tings["WebDAL"];//实现Create Login方法,用于创建Lo gin类实例public static Logind emo.IDAL.ILogin Create Login(){string classn ame = path + ".Login";return (Logind emo.IDAL.ILogin)Assemb ly.Load(path).Create Insta nce(classn ame);}}}IDAL类:usingSystem;usingSystem.Collec tions.Generi c;usingSystem.Text;usingLogind emo.Model;namesp ace Logind emo.IDAL{/// <summar y>/// 登陆用户接口/// </summar y>public interf ace ILogin{/// <summar y>/// 用户登陆/// </summar y>/// <paramname="Log">登陆的Logininf o类型</param> /// <return s></return s>int Logini ng(Logini nfo Log);}}IDAL类:usingSystem;usingSystem.Collec tions.Generi c;usingSystem.Text;namesp ace Logind emo.Model{/// <summar y>/// 用户实体/// </summar y>public classLogini nfo{privat e string _login User;privat e string _login Pass;/// <summar y>/// 获取或设置用户名/// </summar y>public string LoginU ser{set { _login User= value; }get { return _login User; }}/// <summar y>/// 获取或设置用户密码/// </summar y>public string LoginP ass{set { _login Pass= value; }get { return _login Pass; }}}}SQLser ver类库包括两个类文件:Login.cs:usingSystem;usingSystem.Collec tions.Generi c;usingSystem.Text;usingLogind emo.IDAL;usingLogind emo.Model;usingSystem.Data.SqlCli ent;usingSystem.Data;namesp ace Logind emo.SQLser ver{/// <summar y>/// 登陆用户/// </summar y>public classLogin:ILogin{privat e conststring SQL_SE LECT_USER= "SELECT LoginU ser,LoginP assWo rd from LoginU ser WHERELoginU ser=@LoginU ser and LoginP assWo rd=@LoginP assWo rd";privat e conststring LOGIN_USER="@LoginU ser";privat e conststring LOGIN_PASS= "@LoginP assWo rd";/// <summar y>/// 用户登陆/// </summar y>/// <paramname="Log">登陆的Logininf o类型</param>/// <return s></return s>public int Logining(Logininfo Log) //重写ILogin的Lo ginin g接口{SqlPar amete r[] loginP arame ter = GetLog inPar amete rs();int loginS tate;loginP arame ter[0].Value= Log.LoginU ser;loginP arame ter[1].Value= Log.LoginP ass;using(SqlDat aRead er sdr = SqlHel per.Execut eRead er(SqlHel per.Con, Comman dType.Text, SQL_SE LECT_USER, loginP arame ter)){if (sdr.Read()){loginS tate= 1;}else{loginS tate= 0;}sdr.Dispos e();}return loginS tate;}/// <summar y>/// 获取SQL参数缓存/// </summar y>/// <returns>参数数组</return s>privat e static SqlPar amete r[] GetLog inPar amete rs(){SqlPar amete r[] parms= SqlHel per.GetCac hedPa ramet ers(SQL_SE LECT_USER);if (parms== null){parms= new SqlPar amete r[]{new SqlPar amete r(LOGIN_USER,SqlDbT ype.VarCha r,10),new SqlPar amete r(LOGIN_PASS,SqlDbT ype.VarCha r,10)};SqlHel per.CacheP arame ters(SQL_SE LECT_USER, parms);}return parms;}}}SQLHel per:usingSystem;usingSystem.Config urati on;usingSystem.Data;usingSystem.Data.SqlCli ent;usingSystem.Collec tions;namesp ace Logind emo.SQLser ver{/// <summar y>/// SqlHelper类是专门提供给广大用户用于高性能、可升级和最佳练习的sq l数据操作/// </summar y>public abstra ct classSqlHel per{//数据库连接字符串public static readon ly string Con = System.Config urati on.Config urati onMan ager.AppSet tings["SQLSer ver"];// 用于缓存参数的HASH表privat e static Hashta ble parmCa che = Hashta ble.Synchr onize d(new Hashta ble());/// <summar y>/// 给定连接的数据库用假设参数执行一个sql命令(不返回数据集)/// </summar y>/// <paramname="connec tionS tring">一个有效的连接字符串</param>/// <paramname="commandType">命令类型(存储过程, 文本, 等等)</param>/// <paramname="commandT ext">存储过程名称或者sql命令语句</param>/// <paramname="commandPara meter s">执行命令所用参数的集合</param>/// <returns>执行命令所影响的行数</return s>public static int Execut eNonQ uery(string connec tionS tring, Comman dType cmdTyp e, string cmdTex t, params SqlPar amete r[] comman dPara meter s){SqlCom mandcmd = new SqlCom mand();using(SqlCon necti on conn = new SqlCon necti on(connec tionS tring)){Prepar eComm and(cmd, conn, null, cmdTyp e, cmdTex t, comman dPara meter s);int val = cmd.Execut eNonQ uery();cmd.Parame ters.Clear();return val;}}/// <summar y>/// 用现有的数据库连接执行一个sql命令(不返回数据集)/// </summar y>/// <paramname="conn">一个现有的数据库连接</param>/// <paramname="commandType">命令类型(存储过程, 文本, 等等)</param>/// <paramname="commandT ext">存储过程名称或者sql命令语句</param>/// <paramname="commandPara meter s">执行命令所用参数的集合</param>/// <returns>执行命令所影响的行数</return s>public static int Execut eNonQ uery(SqlCon necti on connec tion,Comman dType cmdTyp e, string cmdTex t, params SqlPar amete r[] comman dPara meter s){SqlCom mandcmd = new SqlCom mand();Prepar eComm and(cmd, connec tion, null, cmdTyp e, cmdTex t, comman dPara meter s);int val = cmd.Execut eNonQ uery();cmd.Parame ters.Clear();return val;}/// <summar y>///使用现有的S QL事务执行一个sq l命令(不返回数据集)/// </summar y>/// <remark s>///举例:/// int result= Execut eNonQ uery(connSt ring,Comman dType.Stored Proce dure,"Publis hOrde rs", new SqlPar amete r("@prodid", 24));/// </remark s>/// <paramname="trans">一个现有的事务</param>/// <paramname="commandType">命令类型(存储过程, 文本, 等等)</param>/// <paramname="commandT ext">存储过程名称或者sql命令语句</param>/// <paramname="commandPara meter s">执行命令所用参数的集合</param>/// <returns>执行命令所影响的行数</return s>public static int Execut eNonQ uery(SqlTra nsact ion trans,Comman dType cmdTyp e, string cmdTex t, params SqlPar amete r[] comman dPara meter s){SqlCom mandcmd = new SqlCom mand();Prepar eComm and(cmd, trans.Connec tion, trans, cmdTyp e, cmdTex t, comman dPara meter s);int val = cmd.Execut eNonQ uery();cmd.Parame ters.Clear();}/// <summar y>/// 用执行的数据库连接执行一个返回数据集的sq l命令/// </summar y>/// <remark s>/// 举例:/// SqlDat aRead er r = Execut eRead er(connSt ring,Comman dType.Stored Proce dure,"Publis hOrde rs", new SqlPar amete r("@prodid", 24));/// </remark s>/// <paramname="connec tionS tring">一个有效的连接字符串</param>/// <paramname="commandType">命令类型(存储过程, 文本, 等等)</param>/// <paramname="commandT ext">存储过程名称或者sql命令语句</param>/// <paramname="commandPara meter s">执行命令所用参数的集合</param>/// <returns>包含结果的读取器</return s>public static SqlDat aRead er Execut eRead er(string connec tionS tring, Comman dType cmdTyp e, string cmdTex t, params SqlPar amete r[] comman dPara meter s){//创建一个Sq lComm and对象SqlCom mandcmd = new SqlCom mand();//创建一个Sq lConn ectio n对象SqlCon necti on conn = new SqlCon necti on(connec tionS tring);//在这里我们用一个try/catch结构执行sq l文本命令/存储过程,因为如果这个方法产生一个异常我们要关闭连接,因为没有读取器存在,//因此comm andBe havio ur.CloseC onnec tion就不会执行try{//调用Prepar eComm and 方法,对SqlCom mand对象设置参数Prepar eComm and(cmd, conn, null, cmdTyp e, cmdTex t, comman dPara meter s);//调用SqlCom mand的Execut eRead er 方法SqlDat aRead er reader = cmd.Execut eRead er(Comman dBeha vior.CloseC onnec tion);//清除参数cmd.Parame ters.Clear();return reader;}catch{//关闭连接,抛出异常conn.Close();throw;}}/// <summar y>/// 用指定的数据库连接字符串执行一个命令并返回一个数据集的第一列/// </summar y>/// <remark s>///例如:/// Object obj = Execut eScal ar(connSt ring,Comman dType.Stored Proce dure,"Publis hOrde rs", new SqlPar amete r("@prodid", 24));///<paramname="connec tionS tring">一个有效的连接字符串</param>/// <paramname="commandType">命令类型(存储过程, 文本, 等等)</param>/// <paramname="commandT ext">存储过程名称或者sql命令语句</param>/// <paramname="commandPara meter s">执行命令所用参数的集合</param>/// <returns>用Conver t.To{Type}把类型转换为想要的</return s>public static object Execut eScal ar(string connec tionS tring, Comman dType cmdTyp e, string cmdTex t, params SqlPar amete r[] comman dPara meter s){SqlCom mandcmd = new SqlCom mand();using(SqlCon necti on connec tion= new SqlCon necti on(connec tionS tring)){Prepar eComm and(cmd, connec tion, null, cmdTyp e, cmdTex t, comman dPara meter s);object val = cmd.Execut eScal ar();cmd.Parame ters.Clear();return val;}}/// <summar y>/// 用指定的数据库连接执行一个命令并返回一个数据集的第一列/// </summar y>/// <remark s>/// 例如:/// Object obj = Execut eScal ar(connSt ring,Comman dType.Stored Proce dure,"Publis hOrde rs", new SqlPar amete r("@prodid", 24));/// </remark s>/// <paramname="conn">一个存在的数据库连接</param>/// <paramname="commandType">命令类型(存储过程, 文本, 等等)</param>/// <paramname="commandT ext">存储过程名称或者sql命令语句</param>/// <paramname="commandPara meter s">执行命令所用参数的集合</param>/// <returns>用Conver t.To{Type}把类型转换为想要的</return s>public static object Execut eScal ar(SqlCon necti on connec tion,Comman dType cmdTyp e, string cmdTex t, params SqlPar amete r[] comman dPara meter s){SqlCom mandcmd = new SqlCom mand();Prepar eComm and(cmd, connec tion, null, cmdTyp e, cmdTex t, comman dPara meter s);object val = cmd.Execut eScal ar();cmd.Parame ters.Clear();return val;}/// <summar y>/// 将参数集合添加到缓存/// </summar y>/// <paramname="cacheK ey">添加到缓存的变量</param>/// <paramname="cmdPar ms">一个将要添加到缓存的s ql参数集合</param>public static void CacheP arame ters(string cacheK ey, params SqlPar amete r[] comman dPara meter s) {parmCa che[cacheK ey] = comman dPara meter s;}/// 找回缓存参数集合/// </summar y>/// <paramname="cacheK ey">用于找回参数的关键字</param>/// <returns>缓存的参数集合</return s>public static SqlPar amete r[] GetCac hedPa ramet ers(string cacheK ey){SqlPar amete r[] cached Parms = (SqlPar amete r[])parmCa che[cacheK ey];if (cached Parms == null)return null;SqlPar amete r[] cloned Parms = new SqlPar amete r[cached Parms.Length];for (int i = 0, j = cached Parms.Length; i < j; i++)cloned Parms[i] = (SqlPar amete r)((IClone able)cached Parms[i]).Clone();return cloned Parms;}/// <summar y>/// 准备执行一个命令/// </summar y>/// <paramname="cmd">sql命令</param>/// <paramname="conn">Sql连接</param>/// <paramname="trans">Sql事务</param>/// <paramname="cmdTyp e">命令类型例如存储过程或者文本</param>/// <paramname="cmdTex t">命令文本,例如:Select * from Produc ts</param>/// <paramname="cmdPar ms">执行命令的参数</param>privat e static void Prepar eComm and(SqlCom mandcmd, SqlCon necti on conn, SqlTra nsact ion trans,Comman dType cmdTyp e, string cmdTex t, SqlPar amete r[] cmdPar ms){if (conn.State!= Connec tionS tate.Open)conn.Open();cmd.Connec tion= conn;man dText = cmdTex t;if (trans!= null)cmd.Transa ction = trans;man dType = cmdTyp e;if (cmdPar ms != null){foreac h (SqlPar amete r parm in cmdPar ms)cmd.Parame ters.Add(parm);}}}}在web.config文件中配置这个<appSet tings><add key="WebDAL" value="Logind emo.SQLser ver"/><!--实例化类型--><add key="SQLSer ver" value="Server=.\SQL2005;DataBa se=Logind emo;user id=sa;passwo rd=123;"/></appSet tings>。
php设计模式之抽象工厂模式
php设计模式之抽象⼯⼚模式抽象⼯⼚模式(Abstact Factory)是⼀种常见的软件设计模式。
该模式为⼀个产品族提供了统⼀的创建接⼝。
当需要这个产品族的某⼀系列的时候,可以为此系列的产品族创建⼀个具体的⼯⼚类。
⼀、意图抽象⼯⼚模式提供⼀个创建⼀系统相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类【GOF95】⼆、抽象⼯⼚模式结构图三、抽象⼯⼚模式中主要⾓⾊抽象⼯⼚(Abstract Factory)⾓⾊:它声明⼀个创建抽象产品对象的接⼝。
通常以接⼝或抽象类实现,所有的具体⼯⼚类必须实现这个接⼝或继承这个类。
具体⼯⼚(Concrete Factory)⾓⾊:实现创建产品对象的操作。
客户端直接调⽤这个⾓⾊创建产品的实例。
这个⾓⾊包含有选择合适的产品对象的逻辑。
通常使⽤具体类实现。
抽象产品(Abstract Product)⾓⾊:声明⼀类产品的接⼝。
它是⼯⼚⽅法模式所创建的对象的⽗类,或它们共同拥有的接⼝。
具体产品(Concrete Product)⾓⾊:实现抽象产品⾓⾊所定义的接⼝,定义⼀个将被相应的具体⼯⼚创建的产品对象。
其内部包含了应⽤程序的业务逻辑。
四、抽象⼯⼚模式的优缺点抽象⼯⼚模式的优点:1、分离了具体的类2、使增加或替换产品族变得容易3、有利于产品的⼀致性抽象⼯⼚模式的缺点: 难以⽀持新种类的产品。
这是因为AbstractFactory接⼝确定了可以被创建的产品集合。
⽀持新各类的产品就需要扩展访⼯⼚接⼝,从⽽导致AbstractFactory类及其所有⼦类的改变。
抽象⼯⼚就是以⼀种倾斜的⽅式⽀持增加新的产品中,它为新产品族的增加提供了⽅便,⽽不能为新的产品等级结构的增加提供这样的⽅便。
五、抽象⼯⼚模式适⽤场景以下情况应当使⽤抽象⼯⼚模式:1、⼀个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的⼯⼚模式都是重要的。
2、这个系统的产品有多于⼀个的产品族,⽽系统只消费其中某⼀族的产品。
第6章抽象工厂模式
第6章抽象工厂模式抽象工厂模式是一种创建型设计模式,旨在提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体的类。
通过使用抽象工厂模式,可以使客户端与具体实例的创建分离,降低了客户端与具体实例之间的耦合度。
本文将详细介绍抽象工厂模式的定义、结构、应用场景以及优缺点。
一、定义抽象工厂模式,也称为Kit模式,是一种对象创建型模式。
它提供一个接口,用于创建一系列具有共同接口的相关或相互依赖的对象,而无需指定其具体实现类。
二、结构抽象工厂模式包含以下几个角色:1. 抽象工厂(Abstract Factory):定义了创建产品对象的接口,它包含了一组创建产品的方法。
2. 具体工厂(Concrete Factory):实现了抽象工厂中的方法,完成具体产品的创建。
3. 抽象产品(Abstract Product):定义了产品的接口,是具体产品类的父类。
4. 具体产品(Concrete Product):实现了抽象产品接口的具体产品类。
三、应用场景抽象工厂模式通常在以下几种情况下使用:1.系统需要一系列相关或相互依赖的对象,并且不希望客户端与具体实例之间有耦合。
2.客户端不应知道所使用的具体工厂和具体产品类的名称。
3.系统需要提供一种产品的多种实现,用户可以选择使用哪个实现。
四、优缺点抽象工厂模式具有以下优点:1.将具体产品的创建与使用解耦,客户端只需要知道使用抽象工厂即可。
2.通过切换具体工厂,可以改变系统的配置,实现不同产品簇的切换。
3.新增具体工厂和具体产品类只需实现对应的接口,符合开闭原则。
抽象工厂模式的缺点是:1.当产品簇需要新增产品时,需要修改所有的具体工厂类,不符合开闭原则。
2.当具体产品较多时,会导致具体工厂类的数量增加,难以管理。
五、代码示例我们以汽车和轮胎为例,介绍抽象工厂模式的代码实现。
首先,定义抽象工厂和抽象产品的接口:```java//抽象工厂public interface AbstractFactoryCar createCar(;Tire createTire(;//抽象产品public interface Carvoid drive(;//抽象产品public interface Tirevoid rotate(;```然后,实现具体工厂和具体产品的类:```java//具体工厂public class DomesticFactory implements AbstractFactory public Car createCareturn new DomesticCar(;}public Tire createTirreturn new DomesticTire(;}//具体工厂public class ForeignFactory implements AbstractFactory public Car createCareturn new ForeignCar(;}public Tire createTirreturn new ForeignTire(;}//具体产品public class DomesticCar implements Carpublic void drivSystem.out.println("国产汽车开始启动");}//具体产品public class ForeignCar implements Carpublic void drivSystem.out.println("进口汽车开始启动");}//具体产品public class DomesticTire implements Tire public void rotatSystem.out.println("国产轮胎开始旋转");}//具体产品public class ForeignTire implements Tirepublic void rotatSystem.out.println("进口轮胎开始旋转");}```最后,客户端通过具体工厂创建具体产品:```javapublic class Clientpublic static void main(String[] args) AbstractFactory factory = new DomesticFactory(; Car car = factory.createCar(;car.drive(;Tire tire = factory.createTire(;tire.rotate(;factory = new ForeignFactory(;car = factory.createCar(;car.drive(;tire = factory.createTire(;tire.rotate(;}```运行客户端代码输出:```国产汽车开始启动国产轮胎开始旋转进口汽车开始启动进口轮胎开始旋转```通过抽象工厂模式,客户端代码无需关注具体的产品类,只需要通过工厂创建产品即可。
三层架构的实现方法
三层架构的实现方法三层架构是一种常用的软件架构模式,它将应用程序分为三个独立的层次:表示层、业务逻辑层和数据访问层。
这种架构模式的设计目标是实现系统的高内聚性和低耦合性,以便提高软件的可维护性、可扩展性和可重用性。
表示层是用户与系统交互的界面,负责接收用户的输入并将其转发给业务逻辑层进行处理。
表示层通常包括用户界面和展示逻辑,可以是Web页面、移动应用或桌面应用等。
在三层架构中,表示层应该尽可能简单,只负责接收和展示数据,不涉及具体的业务逻辑。
这样可以使表示层更易于修改和替换,而不会对其他层产生影响。
业务逻辑层是整个系统的核心,负责处理业务逻辑和业务规则。
它接收表示层传递过来的请求,并进行相应的处理,包括数据处理、业务计算、流程控制等。
业务逻辑层是三层架构中最重要的一层,它起到了连接表示层和数据访问层的桥梁作用。
在设计业务逻辑层时,应该将业务逻辑尽可能地抽象出来,以提高系统的可复用性和可测试性。
数据访问层是与数据库进行交互的层次。
它负责对数据的持久化和访问,通过封装数据库操作来隐藏数据库的细节。
数据访问层可以使用各种技术来实现,比如关系型数据库、非关系型数据库或者ORM框架等。
在三层架构中,数据访问层应该与具体的数据库实现解耦,以便在需要更换数据库时能够轻松地进行迁移。
三层架构的实现方法可以通过以下步骤进行:1. 首先,确定系统的需求,并进行需求分析。
根据需求分析的结果,确定系统的功能模块和业务流程。
2. 然后,将系统的功能模块划分为不同的层次。
一般情况下,可以将表示层、业务逻辑层和数据访问层作为三个独立的层次。
3. 接下来,设计表示层。
根据系统的需求和用户交互方式,设计用户界面和展示逻辑。
表示层应该尽量简单,只负责接收和展示数据。
4. 然后,设计业务逻辑层。
根据系统的需求和业务规则,设计业务逻辑和业务流程。
业务逻辑层应该尽量抽象,以提高系统的可复用性和可测试性。
5. 最后,设计数据访问层。
根据系统的需求和数据库设计,设计数据访问层的接口和实现。
抽象工厂(Abstract Factory)模式
抽象工厂(Abstract Factory)模式一、抽象工厂(Abstract Factory)模式抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
为了方便引进抽象工厂模式,引进一个新概念:产品族(Product Family)。
所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。
如图:图中一共有四个产品族,分布于三个不同的产品等级结构中。
只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。
引进抽象工厂模式所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。
如果用图来描述的话,如下图:二、 Abstract Factory模式的结构:图中描述的东西用产品族描述如下:抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。
这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。
这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
三、程序举例:该程序演示了抽象工厂的结构,本身不具有任何实际价值。
// Abstract Factory pattern -- Structural exampleusing System;// "AbstractFactory"abstract class AbstractFactory{// Methodsabstract public AbstractProductA CreateProductA();abstract public AbstractProductB CreateProductB();}// "ConcreteFactory1"class ConcreteFactory1 : AbstractFactory{// Methodsoverride public AbstractProductA CreateProductA(){return new ProductA1();}override public AbstractProductB CreateProductB(){return new ProductB1();}}// "ConcreteFactory2"class ConcreteFactory2 : AbstractFactory{// Methodsoverride public AbstractProductA CreateProductA() {return new ProductA2();}override public AbstractProductB CreateProductB() {return new ProductB2();}}// "AbstractProductA"abstract class AbstractProductA{}// "AbstractProductB"abstract class AbstractProductB{// Methodsabstract public void Interact( AbstractProductA a ); }// "ProductA1"class ProductA1 : AbstractProductA{}// "ProductB1"class ProductB1 : AbstractProductB{// Methodsoverride public void Interact( AbstractProductA a ){Console.WriteLine( this + " interacts with " + a );}}// "ProductA2"class ProductA2 : AbstractProductA{}// "ProductB2"class ProductB2 : AbstractProductB{// Methodsoverride public void Interact( AbstractProductA a ){Console.WriteLine( this + " interacts with " + a );}}// "Client" - the interaction environment of the products class Environment{// Fieldsprivate AbstractProductA AbstractProductA;private AbstractProductB AbstractProductB;// Constructorspublic Environment( AbstractFactory factory ){AbstractProductB = factory.CreateProductB();AbstractProductA = factory.CreateProductA();}// Methodspublic void Run(){AbstractProductB.Interact( AbstractProductA );}}///<summary>/// ClientApp test environment///</summary>class ClientApp{public static void Main(string[] args){AbstractFactory factory1 = new ConcreteFactory1();Environment e1 = new Environment( factory1 );e1.Run();AbstractFactory factory2 = new ConcreteFactory2();Environment e2 = new Environment( factory2 );e2.Run();}}四、在什么情形下使用抽象工厂模式:在以下情况下应当考虑使用抽象工厂模式:∙一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
L09B抽象工厂模式
源代码
下面给出这个系统所有的源代码。 首先给出工厂角色的源代码,可以看出,抽象工厂角色规定出两个工厂方法,分别 提供两个不同等级结构的产品对象。 代码清单1:抽象产品角色的源代 package com.javapatterns.abstractfactory; public interface Creator { /** * 产品等级结构A 的工厂方法 */ public ProductA factoryA(); /** * 产品等级结构B 的工厂方法 */ public ProductB factoryB(); }
可以看出,一个工厂等级结构可以创建出分属于不同产品等级结构的一 个产品族中的所有对象;显然,这时候抽象工厂模式比工厂方法模式更 有效率。如果使用相图来描述的话,就如下面的类图所示。 可以看出,对应于每一个产品族都有一个具体工厂。而每一个具体工厂 负责创建属于同一个产品族、但是分属于不同等级结构的产品。
产品对象的创建问题:
通过使用抽象工厂模式,可以处理具有相同(或者相似)等级结构的多 个产品族中的产品对象创建问题。比如下面就是两个具有相同等级结构 的产品等级结构A 和产品等级结构B 的结构图。
如果使用相图描述的话,会看到在相图上出现两个等级结构A 和B,以 及两个产品族1 和2。如下图所示。 在下面的相图中,每一个坐标点都代表一个具体产品角色。
下面是产品等级结构B 的抽象产品角色,这个抽象产品角色也是由一个Java 接 口实现的。 代码清单7:抽象产品角色ProductB 的源代码 package com.javapatterns.abstractfactory; public interface ProductB { } 下面是属于产品等级结构B 的具体产品类ProductB1 的源代码。这个具体产品实 现了产品等级结构B 的抽象产品接口。 代码清单8:具体产品类ProductB1 的源代码 package com.javapatterns.abstractfactory; public class ProductB1 implements ProductB { /** * 构造子 */ public ProductB1() { } }
抽象工厂模式_Python设计模式(第2版)_[共3页]
30第3章工厂模式:建立创建对象的工厂
实现哪些类取决于接口(Product),而不是ConcreteProduct类。
•它们是松耦合的,因为创建对象的代码与使用它的代码是分开的。
客户端完全不需要关心要传递哪些参数以及需要实例化哪些类。
由于添加新类更加容易,所以降低了维护成本。
3.4 抽象工厂模式
抽象工厂模式的主要目的是提供一个接口来创建一系列相关对象,而无需指定具体的类。
工厂方法将创建实例的任务委托给了子类,而抽象工厂方法的目标是创建一系列相关对象。
如图3-5所示,ConcreteFactory1和ConcreteFactory2是通过AbstractFactory接口创建的。
此接口具有创建多种产品的相应方法。
图3-5
ConcreteFactory1和ConcreteFactory2实现了AbstractFactory,并创建实例ConcreteProduct1、ConcreteProduct2、AnotherConcreteProduct1和AnotherConcreteProduct2。
在这里,ConcreteProduct1和ConcreteProduct2是通过AbstractProduct 接口创建的,而AnotherConcreteProduct1和AnotherConcreteProduct2则是通过AnotherAbstractProduct接口创建的。
实际上,抽象工厂模式不仅确保客户端与对象的创建相互隔离,同时还确保客户端能够使用创建的对象。
但是,客户端只能通过接口访问对象。
如果要使用一个系列中的多个。
在三层结构中使用抽象工厂设计模式
关键词
当今的管理信息 系统 人多都是涉及数据库 济 的 ,且人部 分都涉 及到关系数据 库的 访问 。对编程人 员来 说,如果程序中的数据 库访f u j 都是在窗体程序 中完成的 ,这是相 当麻烦的事 。由于在软 件体系槊{ 句 设汁中 。 分层式结构是最常见 ,也是最重要的一种结构 , 以编 狴人 所 员在 设汁 序过程 中多采川三层架构来将界面层 、业务逻 辑层 、数据 程 访问层分开 来减少重新编程的麻烦 分层结构的设汁离不开对 没汁模 式的灵活应 川 ,没计模式会使系统开发者更舢容易理解其 没计思路 . 简单方便地复用成功的没计和体系结 构造
装 S L Sre 据 访 问 对 象 的 创 建 ; A cs S r r 体 工 厂 Q e r v数 ce e e具 s v ( ces A F c r 类 ,用 于 封 装 A cs Sre 据 访 问对 象的 创 A cs L a o ) D ty ce e r s v 数 建。
实现抽象工厂类:
p b i b ta t l s sr cDALF cO y u l a s r c a sAb ta t c c a tr
在. T N叵 框架下程 序 员多采心三层 架构来构建 数据库应 川系统 , 以减少重新编程的麻烦。 表示层是 位于最外层 ,离川户最近的层 .州于显示数据和接收用 户输入 的数据 ,为用户提供一种交互式操作界面 数据 访问层主要实 现对数据保存和读取操作 ,即增删 查改 。业务逻辑层是界面层和 数据
1 抽 象 工 厂设 计 模 式
酒 店管理 系统是基于O P O 实现的三层结 构数据 库应H 系统 ,通过 I
在三层结构 中使川抽象工厂没 ’ 十 模式 ,为酒 店管理 系统提供 了多种数
在三层结构中使用抽象工厂设计模式
在三层结构中使用抽象工厂设计模式
马相芬
【期刊名称】《内江科技》
【年(卷),期】2011(32)4
【摘要】本文分析了设计模式、抽象工厂模式、三层结构及其特点,并将抽象工厂模式和三层架构软件系统应用于酒店管理系统中.
【总页数】2页(P127,131)
【作者】马相芬
【作者单位】濮阳职业技术学院数学与信息工程系
【正文语种】中文
【相关文献】
1.抽象工厂设计模式在3层结构开发中的应用
2.MVC设计模式在.NET三层结构开发中的研究和实现
3.抽象工厂设计模式在数据访问中的应用
4.抽象工厂设计模式在MIS中的应用
5.基本解法在三维涂层结构温度场中的应用
因版权原因,仅展示原文概要,查看原文内容请购买。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【“抽象工厂模式”三层架构方法的实现】
摘要:本文主要从用户登陆设计开始,阐述了“抽象工厂”实现过程,并引用Access和Sql2005两种数据库来说明“抽象工厂”设计模式的好处,提出了架构这种模式的具体方法。
关键词:三层架构,简单工厂,抽象工厂
一、概述
一个大的软件项目中包括很多的模块,不同的模块就要创建不同的接口,那么如何返回很多实现接口的对象呢,在简单工厂模式中只能编写多块相似的代码,通过判断条件返回具体的对象,这样就造成大量的代码冗余,采用抽象工厂的方法,可以产生一批有关联的产品,减少程序冗余度,提高程序效率。
二、什么是抽象工厂模式
如图1所示,抽象工厂模式就是实现提供所有具体工厂的接口,基本上为每一个产品种类提供一个创建方法。
在具体工厂中负责创建产品结构中每个产品,它包含了创建不同产品的商业逻辑,实现抽象工厂中的接口,定义产品的共同接口。
三、实现抽象工厂模式的步骤
由上图我们可以看出要想实现抽象工厂模式,大致分为三大步。
简单三层的实现,简单工厂模式的实现,抽象工厂模式的实现。
(一)简单三层的实现
1.新建项目“ThreeLayer”,设计窗体结构。
并标准化命名控件名称。
例如:用户名TEXTBOX控件,name值为“TxtLoginID”。
2.设计数据库并实现数据库的联接。
创建数据库结构,并添加若干条记录,同时导出一份Access数据库。
在项目中新建DbHelper.CS类文件,引用ConfigurationManage以后程序中要用到AppSettings设置。
private static readonly string
msSqlConnectionString=ConfigurationManager.AppSettings[“SqlServerCon nString”];
static SqlConnection cn=new SqlConnection (msSqlConnectionString);
public static SqlConnection GetConnection(bool hasOpen)
{if(hasOpen)cn.Open();else cn.Close();return cn;}
3.实现窗体的登陆功能。
4.数据访问层的实现。
在这个层的代码中提取方法,具体操作是选中代码,右键选择重构下的提取方法,这里注意不要选择用户名和用户密码,这里我们就提取到了有两个参数的方法。
选择的代码都是针对数据操作的,将方法放到DAL数据访问层。
在VS2005中新建项目,填写新的类库,即数据访问层类库(DAL),将刚刚提取的方法从表示层剪切到DAL中。
再在表示层添加对DAL
层的引用,在按钮的Click事件中调用这个方法,我们就实现了从一层到两层的转变,从而实现了最简单的两层结构。
public bool IsAdminUser(string strName,string strPwd){string strSql=“Select count(*)from Admin where LoginId=@Longid and loginPwd=@LonginPwd”}
5.业务逻辑层的实现。
为了重用这些代码,我们把它放到表示层和数据访问层中间,称为业务逻辑层。
下面在前面代码的基础添加一个新的类库即业务逻辑层BLL,然后在BLL层添加具体的方法,引用DAL层的方法,最后在表示层中首先删除对数据访问层的引用,再添加BLL层的引用,更改按钮的Click 的代码为引用BLL层的方法。
这样三层结构就实现了。
public bool IsAdminUser(string strName,string strPwd){return adminDAL.IsAdminUser(strName,strPwd);}
6.引入模型层。
具体的实现方法:添加新的类库,建立实体类,再依次将需要传递的参数作为属性添加到实体类中。
最后添加引用,因为作为数据传递,所以每个层多要引入Model层。
各层引用关系为:用户界面层引用BLL 层,BLL层引用DAL层,各层都引用MODEL层。
(二)简单工厂模式的实现
1.提取接口。
我们在数据访问层使用统一的接口,让访问SQL Server和Access的类都实现这个接口,然后通过接口调用具体的实现。
具体的演示方法是在前面代码的基础上点击DAL层的类,右键选择重构,选择提取接口,这样一个接口就出现了。
新建项目DemoIDAL,添加类库IAdminDAL.CS将形成的接口代码复制到该文件中。
2.引入配置文件(Web.Config)。
在项目中引用CONFIGTION命名空间。
添加连接两程数据库的key值和VALUE及SOURCE值。
3.创建AccessDAL层。
为了可以使用Access库,我们添加新的数据层DemoAccessDAL,再添加一个AccessUserDAL类并实现刚创建的接口,将DAL层中的文件复制到DemoAccessDAL中更改数据库的引用,即将所有代码中有Sql 的字样换成Oledb。
4.创建简单工厂。
实现步骤是创建新的工厂项目类,添加类SimpleFactory,然后在类中实现返回实现产品接口的方法,通过Web.Config 读取配置数据针对不同数据库,返回不同实现接口的对象。
static string
strdbtype=ConfigurationManager.[AppSettings“DBType”];
public static Demo.IDAL.IAdminDAL createadminDAL()
{switch(strdbtype){case“SQL”:return new Demo.DAL.AdminDAL ();case“Access”:
return new Demo.AccessDAL.AdminDAL();default:return null;}}最后修改BLL层的调用方式为简单工厂调用,用接口隐示声明,但是实现通过工厂创建代码为Demo.IDAL.IAdminDAL
adminDAL=Simply.Factory.simplyFactory.createadminDAL();
(三)实现抽象工厂
具体的实现步骤是:首先通过修改前面的编写的简单工厂simpleFactory 类为抽象工厂类,添加相应的抽象方法,通过读取对应的配置文件,返回实现
抽象类的工厂;
public static Abstracfac choosefac()
{switch(strdbtype){case“SQL”:return new SqlFactory();
case“Access”:return new AccessFactory();default:return null;}} public abstract Demo.IDAL.IAdminDAL createuser();
然后创建一个具体工厂类SQLFactory继承这个抽象工厂类,重写抽象方
法,只返回具体SQLServer库的实现;
class SqlFactory:Abstracfac
{public override Demo.IDAL.IAdminDAL createuser(){return new Demo.DAL.AdminDAL();}}
最后创建新的Access具体工厂类,添加类AccessFactory,让它也继承抽
象工厂类,重写抽象方法。
class AccessFactory:Abstracfac
{public override Demo.IDAL.IAdminDAL createuser()
{return new Demo.AccessDAL.AdminDAL();}}
另外不要忘记修改BLL层的调用方式为抽象工厂调用,具体的代码是先得
到一个工厂,然后再得到相应产品。
具体的代码是:
private static AbsDALFactory factory=AbsDALFactory.ChooseFactory ();
private static IUserInfo db=factory.CreateDalUserInfoInstance
();
四、总结
“抽象工厂”在实际编写代码中十分抽象,只要明确抽象工厂的作用是创
建对象提供一般接口,按照从简单三层到简单工厂,再到抽象工厂这样的步骤
去实现“抽象工厂模式”的三层架构,一定会给代码编写及优化带来一定的便利。
参考文献:
[1]徐祗祥.深入.net平台和C#编程[M].2008.
[2]杨明.C#三层架构[M].科学技术文献出版社,2009.
[3]章立民.SQL Server 2005数据库开发实战[M].机械工业出版社,2007. =====本文结束=====TXT&DOC=====2011/3=====。