設計模式- 使用抽象工廠實現多數據庫切換實現過程

  目前我對設計模式方面瞭解的不多,會的設計模式五根手指頭就能數完。怎麼寫好設計模式讓讀者看懂真的要講究一下技巧,不能單純的貼代碼並對代碼作解釋,我覺的《大話設計模式》就是一本講設計模式很好的書,那本書通過故事的形式講解讓人聯想思考下去。

  由於水平有限,所有這篇文章沒什麼講解的,只是寫一下自己使用抽象工廠實現多數據庫切換的實現過程。

 例子的目的

  有時候項目裏使用的是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); 
} 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章