就不能换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等多种商品,而在美国店和中国店要出售本土化的口味 ...
随机推荐
- Day9-Python3基础-多线程、多进程
1.进程.与线程区别 2.python GIL全局解释器锁 3.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Que ...
- PTA笔记 堆栈模拟队列+求前缀表达式的值
基础实验 3-2.5 堆栈模拟队列 (25 分) 设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q. 所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数: int IsFull(Sta ...
- Codeforces Round #617 (Div. 3)F. Berland Beauty
题意: 给一棵树,边权未知,现在给m组约束,每组约束给出从u到v路径中的最小值,现在让你给出一组边权,使得符合之前的约束,不能给出输出-1 思路: 因为n较小,对于每组约束我们可以直接暴力修改路径上的 ...
- Windbg实用手册
Windbg工作中用的不多,所以命令老是记不住,每次使用都要重新查命令,挺烦. 趁这次培训的机会好好测试和总结了一下,下次再用就方便多了. 在这里一起共享一下,如果有错误,请指正. 基本知识和常用命令 ...
- Spring Boot自动装配原理源码分析
1.环境准备 使用IDEA Spring Initializr快速创建一个Spring Boot项目 添加一个Controller类 @RestController public class Hell ...
- win10系统安装VMware虚拟机软件以及linux系统
一.安装VMware 1.在VMware官网下载VMware Workstation Pro 15.5.1 下载地址:https://my.vmware.com/cn/web/vmware/detai ...
- 《N诺机试指南》(七)排版类问题
1.菱形问题: 解析: 主要通过打印空格和星形来打印整个图形,将整体分为=上三角形+下三角形 首先观察上三角形可以发现:第一行2个空格1个星.第二行1个空格3个星.第三行0个空格5个星 空格数 ...
- [1天搞懂深度学习] 读书笔记 lecture I:Introduction of deep learning
- 通常机器学习,目的是,找到一个函数,针对任何输入:语音,图片,文字,都能够自动输出正确的结果. - 而我们可以弄一个函数集合,这个集合针对同一个猫的图片的输入,可能有多种输出,比如猫,狗,猴子等, ...
- Thread类的interrupted方法和isInterrupted方法的区别
如下所示,interrupted()会改变线程的中断状态(清除),而isInterrupted()不影响线程的中断状态 /** * Tests whether the current thread ...
- 20200116--python学习第十天
今日内容 1.参数 2.作用域 3.函数嵌套 内容回顾 线上操作系统:centos py2和py3的区别? 每种数据类型,列举你了解的方法. 3 or 9 and 8 字符串的反转 is 和 == 的 ...