先讲一下简单工厂模式、工厂方法模式、抽象工厂模式的东西:

  • 简单工厂模式(Simple Factory Pattern):工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关类,也就是说产品的创建逻辑集中于一个工厂类,客户端只需要传递不同的参数给工厂,这时情况是:一个工厂创建一个产品,所有的具体工厂继承自一个抽象工厂;对于客户端来说,不存在与具体产品的依赖;
  • 工厂方法模式(Factory Method Pattern):提前定义用于创建对象的接口,让子类决定实例化具体的某一个类,即在工厂和产品中间增加接口,工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例去实现;
  • 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系统或相互依赖对象的接口,不需要指定具体类。抽象工厂正如其名字所说,它抽象的是工厂接口,因此它面向的是多个平等等级结构,其建立对象的原则是以功能相似的对象为单位划分需要建立的对象。

简单工厂并不属于23种基本设计模式中,它是抽象工厂模式的一个特例;抽象工厂与工厂方法区别在于它们抽象的对象不同:工厂方法针对产品进行抽象,而抽象工厂抽象针对工厂。因此可以认为工厂方法是抽象工厂的一种极端情况,工厂方法模式用来创建一个产品的等级结构,它一般只有一个方法,创建一种产品;而抽象工厂是用来创建多个产品的等级结构,一般有多个方法,创建一系列产品。

手机号码查询设计

此程序主要功能就是根据手机号码段查询相应的号码归属地。数据来自网络,数据表结构如下

数据记录超过17万条

这里我使用了Sqlite数据库,将此数据库文件转换为Sqlite数据库文件。

主程序界面设计如下:

业务逻辑分析

主程序调用业务逻辑层BLL,BLL使用抽象工厂DALFactory方法,DALFactory创建DAO实例对象,接口层IDAL定义数据操作接口方法,由数据访问层通过各自的公用数据操作类库进行读写数据库,实现对实体类Model的访问。

解决方案文件列表如图

其中DBUtility为公共数据访问类库。三个数据访问层SQLServerDAL、SqliteDAL和OleDAL分别对应Sql Server、Sqlite、Access数据库。这里我正在使用的是SqliteDAL。

具体实现

建立实体类进行对象封装

App.config定义选用的DAL及数据库连接信息

代码

publicclass list
{
privateint id;
///<summary>
/// 编号
///</summary>
publicint Id
{
get { return id; }
set { id = value; }
}
privatestring num;
///<summary>
/// 号码段(手机号前7位)
///</summary>
publicstring Num
{
get { return num; }
set { num = value; }
}
privatestring code;
///<summary>
/// 邮政编码
///</summary>
publicstring Code
{
get { return code; }
set { code = value; }
}
privatestring city;
///<summary>
/// 城市
///</summary>
publicstring City
{
get { return city; }
set { city = value; }
}
privatestring cardtype;
///<summary>
/// 卡类型
///</summary>
publicstring Cardtype
{
get { return cardtype; }
set { cardtype = value; }
}
}
代码

<?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>
publicstaticclass SqlConnString
{
    publicstaticstring 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>
publicsealedclass ObjectCreate
{
/*所使用程序集*/
publicstaticreadonlystring asseblyDAL = System.Configuration.ConfigurationManager.AppSettings["DAL"];

///<summary>
/// 创建对象(不使用缓存:B/S使用)
///</summary>
///<param name="AssemblyPath"></param>
///<param name="classNamespace"></param>
///<returns></returns>
privatestaticobject CreateObject(string AssemblyPath, string classNamespace)
{
try
{
object objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace);
return objType;
}
catch
{
returnnull;
}
}

///<summary>
/// 创建list接口对象
///</summary>
///<returns></returns>
publicstatic CuteMobileSearch.IDAL.Ilist CreateListObj()
{
string className = asseblyDAL +".listServices";
object obj = CreateObject(asseblyDAL, className);
return (CuteMobileSearch.IDAL.Ilist)obj;
}
}

IDAL声明数据访问的接口方法

代码

publicinterface 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

代码

].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

废话

我知道这篇文章技术一般,显然达不到cnblogs的技术层次;我本人的技术水平在cnblogs牛人面前也只是小菜鸟而已,发到首页是希望大家多多拍砖,多提宝贵意见,:)

编译后程序下载(只含Sqlite数据库):点击下载

源码下载地址(含SqlServer及Sqlite数据库):点击下载

单独Access数据库下载:点击下载

使用工厂方法模式实现多数据库WinForm手机号码查询器(附源码)的更多相关文章

  1. 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

    原文:极限挑战-C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方 ...

  2. C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

    作者: Aicken(李鸣)  来源: 博客园  发布时间: 2010-09-08 15:00  阅读: 4520 次  推荐: 0                   原文链接   [收藏] 摘要: ...

  3. [WinForm]FastColoredTextBox控件(附源码)

    Fast Colored TextBox is text editor component for .NET. Allows you to create custom text editor with ...

  4. 工厂方法模式——创建型模式02

    1. 简单工厂模式     在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...

  5. PHP设计模式(二)工厂方法模式(Factory Method For PHP)

    简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...

  6. Java设计模式 之 工厂方法模式

    1. 使用设计模式的好处:可提高代码的重复性,让代码更容易被他人理解,保证代码的可靠性. 2. 工厂模式定义:就是创建一个工厂类来创建你需要的类,工厂模式包括工厂模式和抽象工厂模式,抽象工厂模式是工厂 ...

  7. 深入浅出设计模式——工厂方法模式(Factory Method)

    介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...

  8. JAVA设计模式之工厂方法模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述工厂方法模式的: 工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymor ...

  9. 六个创建模式之工厂方法模式(Factory Method Pattern)

    问题: 在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则. 定义: 定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类.此时工厂和产品都具有相同的继承结构,抽象产 ...

随机推荐

  1. 使用Dapper进行参数化查询

    在使用Dapper操作Mysql数据库中我介绍了使用dapper进行CURD基本操作,但在示例代码中参数虽然也是通过@开头,但其实不是真正意义的参数化查询,而是拼接sql,这种方式不利于防止sql注入 ...

  2. PHP-FPM进程池探秘

    PHP 支持多进程而不支持多线程:PHP-FPM 在进程池中运行多个子进程并发处理所有连接请求.通过 ps 查看PHP-FPM进程池(pm.start_servers = 2)状态如下: root@d ...

  3. Anroid四大组件service之本地服务

    服务是Android四大组件之一,与Activity一样,代表可执行程序.但Service不像Activity有可操作的用户界面,它是一直在后台运行.用通俗易懂点的话来说: 如果某个应用要在运行时向用 ...

  4. 查漏补缺系列之dapper初体验

    什么是dapper 在维护一些较老的项目的时候,往往我们会用很多sql那么这个时候我们要考虑优化这些项目的时候,我们就可以使用dapper dapper 是一款轻量级的ORM框架,它的优势很多轻量级, ...

  5. java将map拼接成“参数=值&参数=值”

    Java将Map拼接成"参数=值&参数=值" 把一个map的键值对拼接成"参数=值&参数=值"即"username=angusbao& ...

  6. python第二课

    本节内容 1.列表list.切片 2.字典dict

  7. 【ASP.NET MVC 学习笔记】- 01 理解MVC模式

    本文参考:http://www.cnblogs.com/willick/p/3195560.html 1.MVC模式是软件系统的一种架构模式,它将软件分为三大模块: 模型(Model):封装业务逻辑以 ...

  8. 25.Linux-Nor Flash驱动(详解)

    1.nor硬件介绍: 从原理图中我们能看到NOR FLASH有地址线,有数据线,它和我们的SDRAM接口相似,能直接读取数据,但是不能像SDRAM直接写入数据,需要有命令才行 1.1其中我们2440的 ...

  9. 微信退款流程,以及在过程中遇见的错误和解决方式(php 语言)

    官方下载demo 1:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 开发步骤  :    https://pay.weix ...

  10. Java基础-Random类(05)

    随机数(Random) 作用:用于产生一个随机数 使用步骤(和Scanner类似) 导包import java.util.Random; 创建对象Random r = new Random(); 获取 ...