关于工厂模式
先讲一下简单工厂模式、工厂方法模式、抽象工厂模式的东西:
简单工厂并不属于23种基本设计模式中,它是抽象工厂模式的一个特例;抽象工厂与工厂方法区别在于它们抽象的对象不同:工厂方法针对产品进行抽象,而抽象工厂抽象针对工厂。因此可以认为工厂方法是抽象工厂的一种极端情况,工厂方法模式用来创建一个产品的等级结构,它一般只有一个方法,创建一种产品;而抽象工厂是用来创建多个产品的等级结构,一般有多个方法,创建一系列产品。
手机号码查询设计
此程序主要功能就是根据手机号码段查询相应的号码归属地。数据来自网络,数据表结构如下
数据记录超过17万条
这里我使用了Sqlite数据库,将此数据库文件转换为Sqlite数据库文件。
主程序界面设计如下:
业务逻辑分析
主程序调用业务逻辑层BLL,BLL使用抽象工厂DALFactory方法,DALFactory创建DAO实例对象,接口层IDAL定义数据操作接口方法,由数据访问层通过各自的公用数据操作类库进行读写数据库,实现对实体类Model的访问。
解决方案文件列表如图
其中DBUtility为公共数据访问类库。三个数据访问层SQLServerDAL、SqliteDAL和OleDAL分别对应Sql Server、Sqlite、Access数据库。这里我正在使用的是SqliteDAL。
具体实现
建立实体类进行对象封装
- public class list
- {
- private int id;
- /// <summary>
- /// 编号
- /// </summary>
- public int Id
- {
- get { return id; }
- set { id = value; }
- }
- private string num;
- /// <summary>
- /// 号码段(手机号前7位)
- /// </summary>
- public string Num
- {
- get { return num; }
- set { num = value; }
- }
- private string code;
- /// <summary>
- /// 邮政编码
- /// </summary>
- public string Code
- {
- get { return code; }
- set { code = value; }
- }
- private string city;
- /// <summary>
- /// 城市
- /// </summary>
- public string City
- {
- get { return city; }
- set { city = value; }
- }
- private string cardtype;
- /// <summary>
- /// 卡类型
- /// </summary>
- public string Cardtype
- {
- get { return cardtype; }
- set { cardtype = value; }
- }
- }
App.config定义选用的DAL及数据库连接信息
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <appSettings>
- <!--<add key="DAL" value="CuteMobileSearch.SQLServerDAL"/>
- <add key="DAL" value="CuteMobileSearch.SQLiteDAL"/>
- <add key="DAL" value="CuteMobileSearch.OleDAL"/>-->
- <!--当前使用DAL;可选以上三者之一,分别对应Sql Server、Sqlite、Access数据库-->
- <add key="DAL" value="CuteMobileSearch.SQLiteDAL"/>
- <add key="SqlConn" value="server=.;database=CuteMobileDB;uid=sa;pwd=123456"/>
- <add key="SqliteFile" value="/App_Data/db.db"/>
- <add key="OleFile" value="/App_Data/mobile.mdb"/>
- </appSettings>
- </configuration>
SqlConnStr.cs文件用于获得相应的连接字符串ConnectionString
- /// <summary>
- /// 获得连接字符串ConnectingString
- /// </summary>
- public static class SqlConnString
- {
- public static string ReturnConnString()
- {
- string _appPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;//当前程序路径
- string _dal = System.Configuration.ConfigurationManager.AppSettings["DAL"];//获取App.Config中DAL
- string _conn = "";
- switch (_dal)
- {
- /*Sqlite数据库*/
- case "CuteMobileSearch.SQLiteDAL":
- default:
- _appPath = "Data Source=" + _appPath;
- _appPath += System.Configuration.ConfigurationManager.AppSettings["SqliteFile"];
- return _appPath;
- /*SqlServer数据库*/
- case "CuteMobileSearch.SQLServerDAL":
- _conn = "server=.;database=CuteMobileDB;uid=sa;pwd=123456";
- return _conn;
- /*access数据库*/
- case "CuteMobileSearch.OleDAL":
- _appPath = "provider=microsoft.jet.oledb.4.0;data source=" + _appPath + System.Configuration.ConfigurationManager.AppSettings["OleFile"];
- return _appPath;
- }
- }
- }
然后是抽象工厂DAL通过使用反射创建接口对象的实例
- /// <summary>
- /// 创建抽象工厂
- /// </summary>
- public sealed class ObjectCreate
- {
- /*所使用程序集*/
- public static readonly string asseblyDAL = System.Configuration.ConfigurationManager.AppSettings["DAL"];
- /// <summary>
- /// 创建对象(不使用缓存:B/S使用)
- /// </summary>
- /// <param name="AssemblyPath"></param>
- /// <param name="classNamespace"></param>
- /// <returns></returns>
- private static object CreateObject(string AssemblyPath, string classNamespace)
- {
- try
- {
- object objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace);
- return objType;
- }
- catch
- {
- return null;
- }
- }
- /// <summary>
- /// 创建list接口对象
- /// </summary>
- /// <returns></returns>
- public static CuteMobileSearch.IDAL.Ilist CreateListObj()
- {
- string className = asseblyDAL + ".listServices";
- object obj = CreateObject(asseblyDAL, className);
- return (CuteMobileSearch.IDAL.Ilist)obj;
- }
- }
IDAL声明数据访问的接口方法
- public interface Ilist
- {
- /*添加对象*/
- int Add(CuteMobileSearch.Model.list objList);
- /*返回所有*/
- List<CuteMobileSearch.Model.list> GetAll();
- /*根据号码查询*/
- List<Model.list> GetListByNum(string num);
- /*根据查询条件*/
- List<CuteMobileSearch.Model.list> GetListByWhere(string strWhere);
- }
SqliteDAL继承IDAL,实现对数据库的访问和操作,来访问实体类Model
- /// <summary>
- /// 基于Sqlite的数据访问类库
- /// </summary>
- public class listServices : IDAL.Ilist
- {
- /// <summary>
- /// 添加
- /// </summary>
- /// <returns>返回添加数目</returns>
- public int Add(CuteMobileSearch.Model.list objList)
- {
- StringBuilder sbSql = new StringBuilder();
- sbSql.Append("INSERT INTO list(");
- sbSql.Append("num,code,city,cardtype)");
- sbSql.Append(" VALUES(");
- sbSql.Append("@num,@code,@city,@cardtype)");
- sbSql.Append(";SELECT @@IDENTITY");
- SQLiteParameter paras ={
- new SQLiteParameter("@num",DbType.String,8),
- new SQLiteParameter("@code",DbType.String,8),
- new SQLiteParameter("@city",DbType.String,16),
- new SQLiteParameter("@cardtype",DbType.String,16)
- };
- paras[0].Value = objList.Num;
- paras.Value = objList.Code;
- paras.Value = objList.City;
- paras.Value = objList.Cardtype;
- int num = Wang.DBUtility.SqliteHelper.ExecuteCommand(sbSql.ToString());
- return num;
- }
- /// <summary>
- /// 返回List<>
- /// </summary>
- /// <returns></returns>
- public List<CuteMobileSearch.Model.list> GetAll()
- {
- return GetListByWhere("");
- }
- /// <summary>
- /// 根据号码查询
- /// </summary>
- /// <param name="num"></param>
- /// <returns></returns>
- public List<Model.list> GetListByNum(string num)
- {
- string strWhere = "num LIKE '" + num + "%'";
- return GetListByWhere(strWhere);
- }
- /// <summary>
- /// 根据条件返回List<>
- /// </summary>
- /// <param name="strWhere"></param>
- /// <returns></returns>
- public List<CuteMobileSearch.Model.list> GetListByWhere(string strWhere)
- {
- List<CuteMobileSearch.Model.list> listList = new List<CuteMobileSearch.Model.list>();
- StringBuilder strSql = new StringBuilder();
- strSql.Append("SELECT * FROM list");
- if (strWhere != "")
- {
- strSql.Append(" WHERE ");
- strSql.Append(strWhere);
- }
- SQLiteDataReader reader = Wang.DBUtility.SqliteHelper.GetReader(strSql.ToString());
- while (reader.Read())
- {
- CuteMobileSearch.Model.list objList = new CuteMobileSearch.Model.list();
- if (reader["id"].ToString() != String.Empty)
- {
- objList.Id = int.Parse(reader["id"].ToString());
- }
- objList.Num = reader["num"].ToString();
- objList.Code = reader["code"].ToString();
- objList.City = reader["city"].ToString();
- objList.Cardtype = reader["cardtype"].ToString();
- listList.Add(objList);
- }
- reader.Close();
- return listList;
- }
- }
以其中的查询结果的GetListByNum方法的UML类图如下
运行结果
主程序运行效果如下图
查看详细信息
总结
此类基于多数据库操作的应用程序是很常见的,通过使用工厂方法模式进行架构,以业务逻辑分层、抽象实现数据访问的思想进行开发,显然在程序的可扩展性、层次性具有较大的优势。
另一点值得说的是,Sqlite数据库的确在一些应用场合中具有较大的优势,关于Sqlite数据库的介绍请参见此文http://zh.wikipedia.org/wiki/SQLite