目前我對設計模式方面瞭解的不多,會的設計模式五根手指頭就能數完。怎麼寫好設計模式讓讀者看懂真的要講究一下技巧,不能單純的貼代碼並對代碼作解釋,我覺的《大話設計模式》就是一本講設計模式很好的書,那本書通過故事的形式講解讓人聯想思考下去。
由於水平有限,所有這篇文章沒什麼講解的,只是寫一下自己使用抽象工廠實現多數據庫切換的實現過程。
例子的目的
有時候項目裏使用的是ACCESS數據庫,可是突然有一天想更改成MSSQLSERVER數據庫,爲了防止整站代碼重寫這種局面,可以使用抽象工廠+反射實現修改一下配置字符串就能實現ACCESS的MSSQLSERVER數據庫的切換。
實現過程
1、數據庫的建立
爲了例子的講解的方便,我們就只在數據庫裏建立一張表,一張顧客表(Customer)。在MSSQLSERVER數據庫裏創建表的SQL語句如下:
use test;
create table Customer
(
id int identity(1,1) primary key,
cName nvarchar(50),
cPhone nvarchar(50)
)
在ACCESS數據庫裏也一樣創建一張Customer表,字段名一樣。
2、建立項目和類庫的準備工作
先在VS裏面建立一個空的WEB應用程序,我起名爲抽象工廠DEMO,之後建立數據庫的接口類庫IDAL。再建立ACCESS的數據庫訪問類庫爲AccessDAL,SQLServer的數據庫訪問類庫SQLServerDAL。AccessDAL和SQLServerDAL是對IDAL接口類庫的實現,最後再建一個模型層Model。這樣準備工作就好了。大概需要的類庫和項目如下圖所示:
3、對IDAL類庫的代碼實現
在IDAL就要建立一個類,可以在類裏實現對錶的增刪查改等操作。這裏爲了做例子的方便就只實現增和查兩個接口。
建立一個類ICustomer,如下圖所示
//ICustomer.cs接口的代碼
public interface ICustomer
{
bool Insert(Customer customer);
Customer Get(int id);
}
4、對Model層代碼的實現
接口兩個類,Customer.cs 如圖:
namespace Model
{
public class Customer
{
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
private string _cName;
public string CName
{
get { return _cName; }
set { _cName = value; }
}
private string _cPhone;
public string CPhone
{
get { return _cPhone; }
set { _cPhone = value; }
}
}
}
5、對SQLServerDAL類庫裏的代碼的實現
在SQLServerDAL裏建立一個類SQLServerCustomer.cs。實現對ICustomer的接口。如圖:
SQLServerCustomer.cs的代碼 如下:
namespace SQLServerDAL
{
public class SQLServerCustomer : ICustomer
{
public bool Insert(Model.Customer customer)
{
using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "insert into Customer(cName,cPhone) values('" + customer.CName + "','" + customer.CPhone + "');";
cmd.ExecuteNonQuery();
return true;
}
}
}
public Model.Customer Get(int id)
{
using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from Customer where id=" + id;
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
Customer customer = new Customer();
foreach (DataRow row in dt.Rows)
{
customer.CName = dt.Rows[0]["cName"].ToString();
customer.CPhone = dt.Rows[0]["cPhone"].ToString();
customer.Id = id;
}
return customer;
}
}
}
}
}
6、對AccessDAL類庫裏的代碼實現
這裏在做的時候碰到一點問題,ACCESS數據庫我放在WEB項目的DataBase文件夾裏,可是在類庫裏如何WEB項目裏的DataBase文件夾的數據庫文件進行訪問呢?
必須要用到HttpContext.Current.Server.MapPath,在使用這句必需先引用using System.Web;
AccessCustomer.cs的代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using IDAL;
using System.Data;
using System.Data.OleDb;
using Model;
namespace AccessDAL
{
public class AccessCustomer:ICustomer
{
public static string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("/database/db1.mdb");
public bool Insert(Model.Customer customer)
{
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "insert into Customer(cName,cPhone) values('" + customer.CName + "','" + customer.CPhone + "');";
cmd.ExecuteNonQuery();
return true;
}
}
}
public Model.Customer Get(int id)
{
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from Customer where id=" + id;
OleDbDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
Customer customer = new Customer();
foreach (DataRow row in dt.Rows)
{
customer.CName = dt.Rows[0]["cName"].ToString();
customer.CPhone = dt.Rows[0]["cPhone"].ToString();
customer.Id = id;
}
return customer;
}
}
}
}
}
7、使用反射的DataAccess類實現數據庫更改設計
這裏是關鍵,通過反射
可以實現只要更改
private static readonly string AssemblyName = "AccessDAL";
private static readonly string db = "Access";
就能實現對數據庫更改的作用。
上面是使用ACCESS數據庫,如何我突然想更換成MSSQLSERVER數據庫,那麼我只要把這兩句更改成
private static readonly string AssemblyName = "SQLServerDAL";
private static readonly string db = "SQLServer";
就可以了。
先在WEB項目裏建一個類名爲DataAccess。如圖所示:
DataAccess的代碼如下:
namespace 抽象工廠DEMO
{
public class DataAccess
{
//只需要更改這兩處就行了
//private static readonly string AssemblyName = "SQLServerDAL";
//private static readonly string db = "SQLServer";
private static readonly string AssemblyName = "AccessDAL";
private static readonly string db = "Access";
public static ICustomer CreateCustomer()
{
string className = AssemblyName + "." + db + "Customer";
return (ICustomer)Assembly.Load(AssemblyName).CreateInstance(className);
}
}
}
完成這七部就可以了,建一個DEMO.ASPX頁面做一下測試,代碼如下
protected void Button1_Click(object sender, EventArgs e)
{
Customer customer = new Customer();
customer.CName = "demo1";
customer.CPhone = "9999";
ICustomer ic = DataAccess.CreateCustomer();
ic.Insert(customer);
Response.Write("success");
}
protected void Button2_Click(object sender, EventArgs e)
{
Customer customer = new Customer();
ICustomer ic = DataAccess.CreateCustomer();
customer = ic.Get(1);
Response.Write(customer.CName);
}