关闭

C#之三十九 抽象工厂模式

标签: 工厂模式对象工作需求C#框架
2979人阅读 评论(0) 收藏 举报
分类:

在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式

 

重点:

Ø      抽象工厂模式概念

Ø      抽象工厂模式的模型图

Ø      抽象工厂模式访问多种数据库

 

 

预习功课:

Ø      什么是抽象工厂模式

Ø       如何使用抽象工厂模式访问多种数据库

 

 

 

 

 

 

 

 

 

 

 

5.1 抽象工厂模式概述

 

   抽象工厂是一种创建型模式,是为了解决实例化时所带来的问题。这种模式的意图是:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们的具体类。

 

5.1.1 如何不换数据库

 

    假如某公司已经做好了一个企业的电子商务网站,用Sql Server作为数据库;目前又接到类似于该企业需求的项目,但该公司为了省钱,想用Access,那将如何呢?

    Sql Server和Access在Ado.Net上的使用是不同的,在Sql Server上用的是System.Data.SqlClient命名空间下的SqlConnection、SqlCommand、SqlParameter、SqlDataReader、SqlDataAdapter,而Access则要用System.Data.OleDb命名空间下的相应对象。

    另外,二者在Sql语法上也有很多的不同,比如在插入数据时,Access必须要insert into而Sql Server可以不用into;SqlServer中的GetDate()在Access中没有,需要改写成Now();Sql Server中有字符串函数Substring,而Access根本不能用。另外,对于Access中的关键字要用“[]”括起来,否则报错。

    因此,如果有多个同类型的项目,而数据库不同,修改代码的工作量也是空前的,那么有没有一种好的办法,使我们可以根据不同的数据库来执行不同的操作呢?

 

5.1.2 使用抽象工厂模式的数据访问程序




“AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同的实现,而ProductA1、ProductA2和ProductB1、ProductB2就是对两个抽象产品的具体分类的实现,比如ProductA1可以理解为SqlserverUser,而ProductB1是AccessUser。”

    “这么说,Ifactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreateFactory1和ConcreateFactory2就是具体的工厂了。就像SqlserverFactory和AccessFactory一样。通常是在运行时再创建一个ConcreateFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。”

   

5.1.3 抽象工厂模式的优点与缺点

 

抽象工厂模式的优点:

一.易于交换产品系列,由于具体工厂类,例如Ifactoryfactory=new AccessFactory(),在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。

我们的设计不能去防止需求的更改,那么我们的理想便是让改动变得最小,现在如果你要更改数据库访问,我们只需要更改具体工厂就可以做到。

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

 

5.1.4 用反射+抽象工厂的数据访问程序

 

    如果我们现在程序再增加对Oracle的访问,不仅仅需要在抽象工厂中增加一个OracleFactory工厂类,另外还需要在数据访问类的方法的switch方法中增加case。

    这个时候,我们就可以依据字符串db的值去实例化相应的数据库类。就需要用到反射技术了。

    使用反射技术,首先需要引用System.Reflection命名空间,使用反射的写法如下:

    using System.Reflection;   

   

    Iuser  result =(IUser)Assembly.Load("抽 象 工 厂 模 式").CreateInstance;

    现在,我们就可以将程序由编译时转为运行时,由于“CreateInstance(抽象工厂模式.SqlserverUser”)’中的字符串是可以写成变量的,而变量的值到底是Sql Server,还是Access完全可以由事先的那个db变量决定。

    修改过后的数据访问类,用反射技术来实现,取代Ifactory、SqlserverFactory和AccessFactory。代码如下:

   

    using System.Reflection;

   

    class DataAccess

    {

       private static readonly string AssemblyName="抽象工厂模式";

       private static readonly string db="Sqlserver";

 

       public static IUser CreateUser()

    {

       string className=AssemblyName+"."+db+"User";

       return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);

}

public static Idepartment   CreateDepartment()

{

    string className=AssemblyName+"."+"Department";

    return (Ideparment)Assembly.Load(AssemblyName).CreateInstance(className);

}  

}

现在如果我们增加了Oracle数据库访问,相关类的增加是不可避免的,这点无论用任何方法都解决不了,不过这叫扩展,开放-封闭原则性告诉我们,对于扩展,我们开放。但对于修改,我们应该尽量关闭。针对现状,我们需要更改“private static readonly string db="Sqlserver"”为“private static readonly string db="Oracle"”,即(IUser)Assembly.Load(AssemblyName).CreateInstance(className)语句发生了变化。



这样,DataAccess.CreateUser()本来得到的是SqlserverUser的实例,现在就变成了OracleUser的实例了。

 如果需要增加FoodInfo时,则再增加与该FoodInfo相关三个类,再修改

DataAccess,在其中增加一个publicstatic Iproject CreateFoodInfo()方法即可。但是,如果更改数据库,还得去修改程序(修改db的值)并重新编译,是否有更好的方法来解决此问题呢?

 

5.1.5 用反射+配置文件实现数据访问程序

 

    针对上节的问题,我们可以利用配置文件来解决。添加的App.config文件代码如下:

    <?xml version="1.0" encoding="utf-8"?>

<configuration>

    <appSettings>

       <add key="DB" value="Sqlserver"/>

    </appSettins>

</configuration>

在项目上“右键”,手动添加引用System.configuration,并在程序开头增加usingSystem.Configuration,然后更改DataAccess类的字段。

private staticreadonly string db=ConfigurationManager.AppSettings["DB"];

到目前为止,我们应用了反射+抽象工厂模式解决了数据库访问的可维护、可扩展的问题。




0
0
查看评论

C# 设计模式 之 抽象工厂模式

        工厂方法模式在于需要根据条件来控制对哪个类进行实例化,而抽象工厂模式确定实例化的往往设计到多个类,目的是创建一组相关或者相互依赖的对象提供支持!重点就是在于处理一组相关或者相互依赖类!  ...
  • scucj
  • scucj
  • 2007-09-23 01:12
  • 2780

C#设计模式02-抽象工厂模式(附源码)

抽象工厂模式是所有工厂模式中最为抽象的模式,是抽象程度最高的模式,也是最难理解的一种工厂模式。         现在举一个生活中的案例来说明抽象工厂模式,电视是我们生活中必不可说的电器,但是电视有很多厂家,海尔工厂,海信工厂,美的...
  • bhdxmaomi
  • bhdxmaomi
  • 2016-01-12 15:07
  • 1149

抽象工厂模式:实现ASP.NET访问不同数据库

在ASP.NET网站开发中可能会遇到要更换数据库,如将Aceess换为SQL Server ,由于Aceess引用System.Data.OleDb命名空间,SQL Server引用System.Data.SqlClient命名空间。在一般程序代码中我们需要更改连接字符串,ADO....
  • judyge
  • judyge
  • 2015-05-07 08:43
  • 373

抽象工厂模式(abstract)创建型模式 c#简单例子

抽象工厂模式(abstract)创建型模式 c#简单例子 适用于玩家用户数play1、play2....有变化,而行为move、jum无变化时
  • zhgl7688
  • zhgl7688
  • 2014-12-11 19:18
  • 899

【C#设计模式-抽象工厂模式】

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。 应用场景:一个生产集团,在北京的工厂需要生产A类汽车,A类电视;在上海...
  • heyangyi_19940703
  • heyangyi_19940703
  • 2016-04-20 13:04
  • 1978

C#设计模式:抽象工厂方法模式

今天说一下抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产出的具体产品是什么,这样一来,客户就从具体的产品中被解耦我之前说过设计模式:工厂方法模式,我们最后会做一下两种模式的区别我们看用类图看一下...
  • dyllove98
  • dyllove98
  • 2013-02-20 16:29
  • 1051

简单工厂模式+反射来改进抽象工厂模式

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类 用抽象工厂模式来实现数据库访问访问程序作为例子 UML图形 产品抽象类:产品有可能有许多不同的实现 具体产品:对抽象产品的具体实现 工厂类:包含所有产品创建的方法并且能够创建出具体的对象 从这张图形中来理...
  • lypf19900912
  • lypf19900912
  • 2013-03-17 09:54
  • 4142

Asp.net的抽象工厂模式

为什么要使用工厂模式呢?首先
  • wingahi
  • wingahi
  • 2014-05-26 13:40
  • 1748

如何快速生成十九大会议内容摘要

这两天电视和朋友圈都是被十九大的内容刷屏的, 我呢偶尔也关心一下国家大事, 但是又没有时间看几个小时直播,看新闻报道又有些滞后了, 如何能第一时间领会十九大会议精神呢,不如来做一个自动摘要 拢共分三步: 1. 下载直播视频 2. 识别出直播视频中的文本 3. 对文本内容做摘要 ...
  • XiaoPANGXia
  • XiaoPANGXia
  • 2017-10-20 02:00
  • 455

抽象工厂模式的优缺点

优点: 1、抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。 2、当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。 3、增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。   缺点: 增加新的产品等级结...
  • tayanxunhua
  • tayanxunhua
  • 2012-12-01 11:13
  • 11249