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. 基于Flask框架搭建视频网站的学习日志(二)

    基于Flask框架搭建视频网站的学习日志(二)2020/02/02 一.初始化 所有的Flask程序都必须创建一个程序实例,程序实例是Flask类的对象 from flask import Flask ...

  2. 浅谈DFS,BFS,IDFS,A*等算法

    搜索是编程的基础,是必须掌握的技能.--王主任 搜索分为盲目搜索和启发搜索 下面列举OI常用的盲目搜索: 1.dijkstra 2.SPFA 3.bfs 4.dfs 5.双向bfs 6.迭代加深搜索( ...

  3. 如何在国内下载Eclipse及其插件

    北京理工大学 http://mirror.bit.edu.cn/eclipse/ 中国科学技术大学 http://mirrors.ustc.edu.cn/eclipse/ 大连东软信息学院 http: ...

  4. 【WPF学习】第三十九章 理解形状

    在WPF用户界面中,绘制2D图形内容的最简单方法是使用形状(shape)——专门用于表示简单的直线.椭圆.矩形以及多变形的一些类.从技术角度看,形状就是所谓的绘图图元(primitive).可组合这些 ...

  5. qt客户端程序使用svg图片资源的几种方法

    直接使用svg格式文件资源的情况 1. 直接在UI控件属性面板中选择部分支持icon图标的控件的icon来源,这样图标可以显示 2.给toolbutton添加样式 qproperty-icon: ur ...

  6. Linux/UNIX编程:实现简单 tee 命令

    思路很简单,从标准输入文件描述符读入数据,然后同时向标准输出和参数指定的文件写出数据:如果加了 -a 选项,则以追加的方式向文件写出数据.还没了解 getopt() 函数就没判断参数是否合法. #in ...

  7. Go操作MongoDB

    mongoDB是目前比较流行的一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库(NoSQL)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. mongoDB介绍 mon ...

  8. POJ_1050_最大子矩阵

    http://poj.org/problem?id=1050 这道题是最大子串的扩展,遍历过每一个子矩阵就好了,期间用了最大子串的方法. #include<iostream> #inclu ...

  9. (七)mybatis批量操作,分页插件

    首先使用方式很简单: SqlSession sqlSession = sessionFactory.openSession(ExecutorType.BATCH); 批量操作核心:改变执行sql的方式 ...

  10. num14---享元模式

    案例: