就不能换DB吗? 抽象工厂模式
15.1 就不能换DB吗?
15.2 最基本的数据访问程序
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
User user = new User(); SqlserverUser su = new SqlserverUser(); //与SQLServer耦合, su.Insert(user);
su.GetUser(); Console.Read();
}
} //用户类,
class User
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _name; public string Name
{
get { return _name; }
set { _name = value; }
}
} //操作User表类,
class SqlserverUser
{
//新增用户,
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
} //得到用户,
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
} }
15.3 用了工厂方法模式的数据访问程序
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
User user = new User(); //IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory(); IUser iu = factory.CreateUser(); iu.Insert(user);
iu.GetUser(); Console.Read();
}
} class User
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _name; public string Name
{
get { return _name; }
set { _name = value; }
}
} //IUser接口,用于客户端访问,解除与具体数据库的耦合,
interface IUser
{
void Insert(User user); User GetUser(int id);
} //SqlserverUser类,用于访问SQLServer的User,
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
} //AccessUser类,用于访问Access的User,
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
} //IFactory接口,定义一个创建访问User表对象的抽象的工厂接口,
interface IFactory
{
IUser CreateUser();
} //SqlServerFactory类,实现IFactory接口,实例化SqlserverUser,
class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
} //AccessFactory类,实现IFactory接口,实例化AccessUser,
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
} }
15.4 用了抽象工厂模式的数据访问程序
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department(); //IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory(); IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(); IDepartment id = factory.CreateDepartment();
id.Insert(dept);
id.GetDepartment(); Console.Read();
}
} class User
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _name; public string Name
{
get { return _name; }
set { _name = value; }
}
} class Department
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _deptName; public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user); User GetUser(int id);
} class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
} class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
} interface IDepartment
{
void Insert(Department department); Department GetDepartment(int id);
} class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
} class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
}
} interface IFactory
{
IUser CreateUser(); IDepartment CreateDepartment();
} class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
} public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
} class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
} public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
} }
15.5 抽象工厂模式
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类,
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
AbstractFactory factory1 = new ConcreteFactory1();
Client c1 = new Client(factory1);
c1.Run(); AbstractFactory factory2 = new ConcreteFactory2();
Client c2 = new Client(factory2);
c2.Run(); Console.Read();
}
} //抽象产品A,
abstract class AbstractProductA
{
//它们可以有不同的实现,
} //抽象产品B,
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
} //对两个抽象产品A和B的具体分类的实现,
class ProductA1 : AbstractProductA
{ } //对两个抽象产品A和B的具体分类的实现,
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
}
} //对两个抽象产品A和B的具体分类的实现,
class ProductA2 : AbstractProductA
{ } //对两个抽象产品A和B的具体分类的实现,
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
}
} //抽象工厂接口,包含所有产品创建的抽象方法,
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
} //具体工厂,
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
} public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
} //具体工厂,
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA() //运行时创建ConcreteFactory类的实例,具体的工厂再创建具有特定实现的产品对象,
{ //即创建不同的产品对象,客户端应使用不同的具体工厂,
return new ProductA2();
} public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
} class Client
{
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB; public Client(AbstractFactory factory)
{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
} public void Run()
{
AbstractProductB.Interact(AbstractProductA);
}
} }
15.6 抽象工厂模式的优点与缺点
优点:最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置,第二大好处是,它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中,
缺点:抽象工厂模式可以很方便的切换两个数据库访问的代码,但如果你的需求来自增加功能,如增加项目表Project,需要改动哪些部分?至少增加三个类,IProject,SqlserverProject,AccessProject,需更改三个类,IFactory,SqlserverFactory,AccessFactory,并且客户端程序显然不会只有一个,如果有100个调用数据库访问的类,是不是要更改100次 IFactory factory = new AccessFactory( ); 这样的代码才行呢?这不能解决我要更改数据库时,改动一处就完全更改的要求阿,
15.7 用简单工厂来改进抽象工厂
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department(); IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(); IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept);
id.GetDepartment(); Console.Read();
}
} class User
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _name; public string Name
{
get { return _name; }
set { _name = value; }
}
} class Department
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _deptName; public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user); User GetUser(int id);
} class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
} class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
} interface IDepartment
{
void Insert(Department department); Department GetDepartment(int id);
} class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
} class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
}
} class DataAccess
{
private static readonly string db = "Sqlserver"; //与其用IFactory,SqlserverFactory,AccessFactory三个工厂类,
//private static readonly string db = "Access"; //不如直接用一个简单工厂来实现,DataAccess类取而代之它们,
//客户端没有出现任何一个SQLServer或Access的字样,达到了解耦的目的,
public static IUser CreateUser() //客户端已经不在受改动数据库访问的影响了,
{ //但增加数据库访问就麻烦了,
IUser result = null;
switch (db)
{
case "Sqlserver":
result = new SqlserverUser();
break;
case "Access":
result = new AccessUser();
break;
}
return result;
} public static IDepartment CreateDepartment()
{
IDepartment result = null;
switch (db)
{
case "Sqlserver":
result = new SqlserverDepartment();
break;
case "Access":
result = new AccessDepartment();
break;
}
return result;
}
} }
15.8 用反射+抽象工厂的数据访问程序
Assembly.Load("程序集名称").CreateInstance("命名空间.类名称");
原来实例化是写死在程序里的,现在用了反射就可以利用字符串来实例化对象,而变量是可以更换的,即变量"db",
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department(); IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(); IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept);
id.GetDepartment(); Console.Read();
}
} class User
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _name; public string Name
{
get { return _name; }
set { _name = value; }
}
} class Department
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _deptName; public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user); User GetUser(int id);
} class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
} class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
} interface IDepartment
{
void Insert(Department department); Department GetDepartment(int id);
} class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
} class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
}
} class DataAccess
{
//程序集名称,
private static readonly string AssemblyName = "抽象工厂模式"; //数据库名称,
private static readonly string db = "Sqlserver";
//private static readonly string db = "Access"; public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User"; //此处是字符串,可以用变量来处理,也就可以根据需要更换,
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
} public static IDepartment CreateDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
} }
15.9 用反射+配置文件的数据访问程序
namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department(); IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(); IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept);
id.GetDepartment(); Console.Read();
}
} class User
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _name; public string Name
{
get { return _name; }
set { _name = value; }
}
} class Department
{
private int _id; public int ID
{
get { return _id; }
set { _id = value; }
} private string _deptName; public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user); User GetUser(int id);
} class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
} class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
} interface IDepartment
{
void Insert(Department department); Department GetDepartment(int id);
} class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
} class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
}
} class DataAccess
{
private static readonly string AssemblyName = "抽象工厂模式"; //读配置文件,
private static readonly string db = ConfigurationManager.AppSettings["DB"]; public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User";
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
} public static IDepartment CreateDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
} }
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="DB" value="Access"/>
</appSettings>
</configuration>
15.10 无痴迷 不成功
就不能换DB吗? 抽象工厂模式的更多相关文章
- [Python设计模式] 第15章 如何兼容各种DB——抽象工厂模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 如何让一个程序,可以灵活替换数据库? 基础版本 class User(): ...
- C#学习笔记-抽象工厂模式
题目1:数据访问,通过数据库对用户表单的进行访问,数据库包含SQL Server,对用户表单进行“新增用户”和“查询用户”信息等操作. 分析: 首先,确认用户表单,里面包含两个ID和Name两个字段, ...
- C#设计模式之:抽象工厂模式与反射
抽象工厂模式[实例]:定义一个用于创建对象的接口,让子类决定实例化哪一个类 UML 代码class User{ private int _id; public int Id { get = ...
- .NET重构(一):抽象工厂模式实现登录
导读:一路艰辛,我也走到了重构.在重构之前,师傅让用经典三层(UI.BLL.DAL)敲了登录.用户的增删改查,共五条线.从开始对三层的朦胧,到五条线结束,终于对三层有了逻辑上清晰的理解.然后就画了几天 ...
- 面向对象设计模式纵横谈:Abstract Factory 抽象工厂模式(笔记记录)
今天是设计模式的第二讲,抽象工厂的设计模式,我们还是延续老办法,一步一步的.演变的来讲,先来看看一个对象创建的问题. 1.如何创建一个对象 常规的对象创建方法: 这样的创建对象没有任何问题, ...
- Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)
一.抽象工厂模式简介(Bref Introduction) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类.优点 ...
- Java设计模式(三) 抽象工厂模式
原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...
- 《JAVA与模式》之抽象工厂模式
场景问题 举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU.硬盘.内存.主板.电源.机箱等.为讨论使用简单点,只考虑选择CPU和主板的问题. 事实上,在选择 ...
- 设计模式C#实现(五)——抽象工厂模式
抽象工厂模式 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. UML类图: 场景:抽象村商店想销售Pizza和Hamburg等多种商品,而在美国店和中国店要出售本土化的口味 ...
随机推荐
- docker扫盲,面试连这都不会就等着挂吧!
现在很多公司项目部署都是采用K8S docker容器方式,出门面试被问的概率极大,如果被面试官问docker相关知识点直接懵逼,那么基本就是被pass了,除非其他方面技术过硬.所以这种相对前沿的技术, ...
- 基于Flask框架搭建视频网站的学习日志(三)之原始web表单
基于Flask框架搭建视频网站的学习日志(三)1.原始Web 表单 本节主要用于体验一下前端后端直接数据的交互,样例不是太完善,下一节会加入Flash处理,稍微完善一下页面 (备注:建议先阅读廖雪峰老 ...
- 利用geojson实现模型轨迹运动
直接上代码 var viewer = new Cesium.Viewer('cesiumContainer'); //Set the random number seed for consistent ...
- Java 加密/解密Excel
概述 设置excel文件保护时,通常可选择对整个工作簿进行加密保护,打开文件时需要输入密码:或者对指定工作表进行加密,即设置表格内容只读,无法对工作表进行编辑.另外,也可以对工作表特定区域设置保护,即 ...
- C语言系列之预处理指令、循环左移函数的使用(四)
本章节将讲两个知识点 第一个知识点:常用的预处理指令 第二个知识点:循环左移右移函数 第一个知识点:预处理指令 一种预处理指令是#define,他把名字A定义为P0,当这个名字出现在源文件的任何地方时 ...
- 如何快速搭建一个 Node.JS 项目并进入开发?
了解:如何快速搭建一个项目并进入开发? 在此不概述 Node.JS 的历史以及发展过程. 因为之前接触过通过 Java 开发语言,所以明确地知道一个服务器所需的文件,以及一个服务器所需要的操作. 那么 ...
- 二、通过工厂方法来配置bean
调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中. 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节. 要声明通过静态方法创建的 Bean, 需要在 Bean ...
- keywords in my life
在脑子里出现的灵光一现的话语总是美好的: 1.当你试图站在人的发展,历史的发展的角度上看待问题,会发现我们身上所发生的任何事情都是必然的. 2.永远不要以好人的身份去看待和分析一件事情. 3.历史悲剧 ...
- [python之路]学习路线
python基础 #为什么要学python?python在知名公司广泛应用,谷歌.cia.nasa.youtobe.dropbox.instagram.facebook.redhat.豆瓣.知乎.搜狐 ...
- tensorflow variable scope 变量命名空间和变量共享
import tensorflow as tf def f(): var = tf.Variable(initial_value=tf.random_normal(shape=[2])) return ...