使用工厂方法模式实现多数据库WinForm手机号码查询器(附源码)
先讲一下简单工厂模式、工厂方法模式、抽象工厂模式的东西:
- 简单工厂模式(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及数据库连接信息
{
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; }
}
}
<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>
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声明数据访问的接口方法
{
/*添加对象*/
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
/// 基于Sqlite的数据访问类库
///</summary>
publicclass listServices : IDAL.Ilist
{
///<summary>
/// 添加
///</summary>
///<returns>返回添加数目</returns>
publicint 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[1].Value = objList.Code;
paras[2].Value = objList.City;
paras[3].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数据库下载:点击下载
转载于:https://www.cnblogs.com/wwwzzg168/p/3570028.html
使用工厂方法模式实现多数据库WinForm手机号码查询器(附源码)相关推荐
- java 工厂模式_软件设计工厂模式使用场景介绍及java举例(附源码)
工厂模式是软件设计中最常用也最常见的一种模式,这里通过一个例子来说明其功能. 问题背景 用户需求:请提供 1).图形绘制功能,当前可绘制当前可绘制原型.方形.三角形.未来可能需要支持绘制菱形.梯形等形 ...
- 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)
实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方法所耗费的时间. 本实验中所用到工具为VS2008和SQL SERVER 2000.S ...
- dom操作获取盒子宽高位置的三种方法,offset/scroll/client三大家族使用详解(附源码及注释)
结论:页面body的高度==视口的高度+滚动条滚动的距离. 这是一个恒等式,看完本篇博客,你将了解offset/scroll/clent三大事件获取宽高位置的具体含义,运用所学内容可以推导出这样的恒等 ...
- 数据库实现,以及工厂方法模式实现
计算类的定义 using System; using System.Collections.Generic; using System.Linq; using System.Text;namespac ...
- 工厂方法模式和抽象工厂模式
工厂方法模式和抽象工厂模式 工厂方法模式 抽象工厂模式 总结: 工厂方法模式 #include <string> #include <iostream>// Abstract ...
- 设计模式之工厂类模式总结对比、简单工厂模式、工厂方法模式、抽象工厂模式、带反射的工厂模式、例子代码分析、最详细
1. 题目 假设某公司同时用SqlServer.MySql数据库,即会切换两数据库(不同数据库的sql语句有些许差异),同时,两数据库里均有对Users.Departments表的操作(sql代码不一 ...
- 工厂方法模式(Factory Method)
简单工厂(静态工厂方法) 简单工厂实际上不算一种模式,可以把它叫做一种常用写法.例如我们常用的数据库操作,为了适配不同的数据库引擎,可能分别编写了具体的数据库操作类(当然这些类都实现了统一的接口): ...
- 设计模式 | 工厂方法模式及典型应用
工厂方法模式 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化.工厂方法模式让一个类的实例化延迟到其子类. 工厂方法模式又简称为工厂 ...
- 进阶学习(3.2)Factory Method Pattern 工厂方法模式
1 类的实例化不在工厂接口里面实例化, 而是在工厂子类里面实例化 2 使用者无需关注子类工厂里面的逻辑是怎么写的, 只需要知道我调用的这个方法能实 现什么功能, 我不管具体实现 3 需要添加新功 ...
- 《JAVA与模式》之工厂方法模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述工厂方法模式的: 工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymor ...
最新文章
- php 对数据转换成tree,PHP 把返回的數據集轉換成Tree樹
- Android开发之程序员必须要懂得Android的重要设计理念
- python画简单图形-python基础教程之turtle的简单绘图
- 基于BootstarbTable实现加载更多的方式
- OpenCASCADE:Mac OS X平台使用Code::Blocks构建OCCT
- [第一财经周刊] 疯狂的团购
- 今年颜宁在《自然》发表三篇论文仍归清华,网友:可惜以后不是了
- 高性能微服务 Dubbo RPC Redis 分布式框架
- 真奇怪:我机器上的freeswitch无法绑定端口了
- 30m土地利用数据集获取大全/植被类型分布/NDVI数据/NPP数据/径流量数据/降雨量气温气象数据/蒸散量数据/太阳辐射数据
- JavaWeb学习思维导图
- 七种方式实现三栏布局
- VIOS磁盘映射关系确认
- 基本知识 100048
- QT 错误:Unable to create a debugging engine解决
- python学习5(input函数)
- JSF集成Spring
- 哪些编程器可以做丰田智能钥匙OBD全丢?
- oracle中to_date详解
- 如果记录数据库表修改记录
热门文章
- keepalived 邮件通知
- Spring Bean生命周期-prepareRefresh(二)
- React入门(暂缓)
- MySql存储过程的操作
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' 的解决方法
- office2010的安装和卸载
- 安装oracle 10g 的艰难之旅
- 第七章 数据库设计(联系毕业论文))
- 在Lua中“优雅”地使用Protobuf
- mysql call_关于Mysql “CALL语句”