【设计模式】轻巧的变化不同数据库操作 --- 抽象工厂模式

本文主要是介绍【设计模式】轻巧的变化不同数据库操作 --- 抽象工厂模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,概述

        抽象工厂:提供一个创建一些列相关或相互依赖的接口,而无需指定他们具体的类。

 

        抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

        抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。

        抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

         

 

二,示例

 

        概念太抽象了,理解起来实在费劲。看例子,一步一步理解什么是抽象工厂以及抽象工厂的用法及好处。

 

        题目:以前写的网站,用SQL Server  但是后来要更改成Access的数据库或者是Oracle的数据库,改怎么做?

 

1)最基本的数据库访问程序

缺点:如果想将SQL Server数据库操作更改为Access的数据库操作,则需要重写操作类。

            如果表多的话,每一个表的操作都需要更改匹配的 Access数据库操作

 

class Program
{
static void Main(string[] args)
{
User user = new User();
SqlserverUser su = new SqlserverUser();
su.Insert(user);
su.GetUser(1);
Console.Read();
}
}
class User             //用户表(用户ID,用户名)
{
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 SqlserverUser              //操作数据库中User表的类
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
}


2)使用工厂方法模式的数据访问程序

       定义一个用于创建对象的接口,让子类决定实例化哪一类。

      缺点:还是需要指定  AccessFactory()

                   仅仅有一个用户表时候可以应付,如果再添加一个部门表就难以应付

 class Program
{
static void Main(string[] args)
{
User user = new User(); //要处理的表类
//AbstractFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();//抽象工厂,生成具体的类
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
Console.Read();
}
}
class User         //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; }
}
}
interface IUser    //用户表接口
{
void Insert(User user);
User GetUser(int id);
}
class SqlserverUser : IUser //sqlServer操作用户表
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
}
class AccessUser : IUser  //Access操作用户表
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
}
interface IFactory     //工厂接口
{
IUser CreateUser();
}
class SqlServerFactory : IFactory   //sqlServer对象工厂
{
public IUser CreateUser()
{
return new SqlserverUser();
}
}
class AccessFactory : IFactory    //access对象工厂
{
public IUser CreateUser()
{
return new AccessUser();
}
}

 

3)抽象工厂模式

       增加了部门表,通过SQLServer 工厂和 Access 工厂可以生成 操作部门表和用户表的对象

 

class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department();
//AbstractFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = factory.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
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  //具体的sqlServer操作用户表 
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
}
class AccessUser : IUser   //具体的Access操作用户表 
{
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  // 具体sqlServer操作部门表 
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
}
class AccessDepartment : IDepartment   // 具体Access操作部门表 
{
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  //返回sqlServer 操作的不同表对象 
{
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}
class AccessFactory : IFactory    //返回Access 操作的不同表对象 
{
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}


 

三,抽象工厂模式的优点和缺点

 

        1)优点:

               易于交换产品系列,比如从SQLServer 操作系列改变为Access操作系列。仅仅需要将SQLServer工厂改为:  IFactory  factory = new  AccessFactory();

               让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操作实例,产品的类名也被具体工厂的实现分离,不会出现在代码中

         2)缺点:

                如果需要增加一个项目表(project),则需要增加 IProject 、SqlServerProject、AccessProject类,而且还需要更改IFactory、SqlserverFactory、AccessFactory才可以实现,也就是说增加三个类,改变三个类。

 

四,用简单工厂改进抽象工厂

       增加一个DataAccess,和CreateDepartment 代替抽象工厂模式

        缺点:如果需要增加一个Oracle操作,本来增加一个OracleFactory工厂类就可以,现在需要更改以上两个类,违反了开放封闭原则。

 

      

    class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department();
IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
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  //SqlServer操作用户表 
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
}
class AccessUser : IUser //Access操作用户表 
{
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//SqlServer操作部门表 
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
}
class AccessDepartment : IDepartment//SAccess操作部门表 
{
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";
//private static readonly string db = "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;
}
}



 

 

 

 

 

 

 

 

 

 


 

 

这篇关于【设计模式】轻巧的变化不同数据库操作 --- 抽象工厂模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877327

相关文章

Java 字符串操作之contains 和 substring 方法最佳实践与常见问题

《Java字符串操作之contains和substring方法最佳实践与常见问题》本文给大家详细介绍Java字符串操作之contains和substring方法最佳实践与常见问题,本文结合实例... 目录一、contains 方法详解1. 方法定义与语法2. 底层实现原理3. 使用示例4. 注意事项二、su

Oracle数据库在windows系统上重启步骤

《Oracle数据库在windows系统上重启步骤》有时候在服务中重启了oracle之后,数据库并不能正常访问,下面:本文主要介绍Oracle数据库在windows系统上重启的相关资料,文中通过代... oracle数据库在Windows上重启的方法我这里是使用oracle自带的sqlplus工具实现的方

MySQL批量替换数据库字符集的实用方法(附详细代码)

《MySQL批量替换数据库字符集的实用方法(附详细代码)》当需要修改数据库编码和字符集时,通常需要对其下属的所有表及表中所有字段进行修改,下面:本文主要介绍MySQL批量替换数据库字符集的实用方法... 目录前言为什么要批量修改字符集?整体脚本脚本逻辑解析1. 设置目标参数2. 生成修改表默认字符集的语句3

Java Stream流与使用操作指南

《JavaStream流与使用操作指南》Stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于SQL语句操作数据库,本文给大家介绍JavaStream流与使用... 目录一、什么是stream流二、创建stream流1.单列集合创建stream流2.双列集合创建str

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1