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吗? 抽象工厂模式的更多相关文章

  1. [Python设计模式] 第15章 如何兼容各种DB——抽象工厂模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 如何让一个程序,可以灵活替换数据库? 基础版本 class User(): ...

  2. C#学习笔记-抽象工厂模式

    题目1:数据访问,通过数据库对用户表单的进行访问,数据库包含SQL Server,对用户表单进行“新增用户”和“查询用户”信息等操作. 分析: 首先,确认用户表单,里面包含两个ID和Name两个字段, ...

  3. C#设计模式之:抽象工厂模式与反射

    抽象工厂模式[实例]:定义一个用于创建对象的接口,让子类决定实例化哪一个类 UML 代码class User{    private int _id;    public int Id { get = ...

  4. .NET重构(一):抽象工厂模式实现登录

    导读:一路艰辛,我也走到了重构.在重构之前,师傅让用经典三层(UI.BLL.DAL)敲了登录.用户的增删改查,共五条线.从开始对三层的朦胧,到五条线结束,终于对三层有了逻辑上清晰的理解.然后就画了几天 ...

  5. 面向对象设计模式纵横谈:Abstract Factory 抽象工厂模式(笔记记录)

         今天是设计模式的第二讲,抽象工厂的设计模式,我们还是延续老办法,一步一步的.演变的来讲,先来看看一个对象创建的问题. 1.如何创建一个对象 常规的对象创建方法: 这样的创建对象没有任何问题, ...

  6. Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)

    一.抽象工厂模式简介(Bref Introduction) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类.优点 ...

  7. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  8. 《JAVA与模式》之抽象工厂模式

    场景问题 举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU.硬盘.内存.主板.电源.机箱等.为讨论使用简单点,只考虑选择CPU和主板的问题. 事实上,在选择 ...

  9. 设计模式C#实现(五)——抽象工厂模式

    抽象工厂模式 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. UML类图: 场景:抽象村商店想销售Pizza和Hamburg等多种商品,而在美国店和中国店要出售本土化的口味 ...

随机推荐

  1. springIOC源码接口分析(三):ApplicationContext

    一 新增方法 主要都是获取容器基本信息的一些接口,比如获取名称,id和启动时间戳,获取AutowireCapableBeanFactory等接口 二 继承接口 ApplicationContext继承 ...

  2. python3基础

    1.print()函数 支持自动换行: 不自动换行:使用   end=“” print格式化输出: 字符串格式化符号: • %c 格式化字符及其ASCII码• %s 格式化字符串• %d 格式化整数• ...

  3. Flutter开发之Widget学习

    一.Text 组件 属性  textAlign: TextAlign.left,                           -----文本对齐方式  maxLines: 1,        ...

  4. 免费丨十大IT热门学科在线直播体验课正式来袭,全免费!!!

    一场突如其来的疫情阻挡了人与人之间的接触,在这一系列困难面前,无数勇敢的人们挺身而出,千里驰援,默默承担,用行动践行责任与信念,希望与祖国和家人一道共渡难关. 传智播客作为一家致力于“高精尖”IT科技 ...

  5. CCF_ 201403-2_窗口

    用deque模拟. #include<iostream> #include<cstdio> #include<deque> using namespace std; ...

  6. 第2章 Java并行程序基础(一)

    2.1 有关线程你必须知道的事 进程是系统进行资源分配和调度的基本单位,是程序的基本执行实体. 线程就是轻量级进程,是程序执行的最小单位. 线程的生命周期,如图2.3所示. 线程的所有状态都在Thre ...

  7. Linux 内存分析工具——free命令

    在Linux系统经常被用作服务器系统.当服务器内存吃紧的时候,free命令是我们最常使用的内存分析工具. free使用介绍 free命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及 ...

  8. CentOS使用465端口发送邮件

    1)邮件发送示例 方法1:echo "This is a test mail" | mail -s '邮件测试' 452666750@qq.com 方法2:mail -s '服务运 ...

  9. HTTP&HTTPS协议详解之HTTP篇

    一.HTTP简介 01.什么是HTTP HTTP(HyperText Transfer Protocol ,超文本传输协议),是一个基于请求与响应的,无状态的,应用层的协议,常基于TCP/IP协议传输 ...

  10. AtCoder Beginner Contest 156

    https://atcoder.jp/contests/abc156/tasks A - Beginner #include <bits/stdc++.h> #define ll long ...