设计模式之四(抽象工厂模式第一回合)

原文:设计模式之四(抽象工厂模式第一回合)

前言

首先关于抽象工厂模式的学习,我们需要慢慢的,由浅入深的进入。不能单刀直入,否则可能达不到预期学明白的目标。

第一回合  

 首先我们从最简单的数据访问程序开始吧。

下面先来看一个简单的小例子,代码很简单

public class User
{
    public int ID{get;set;}

    public string Name{get;set;}
}

一个简单的实体类,也相当于在SqlServer数据库中建立了相同的数据表

public class SqlServerUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在SQL Server 中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在SQL Server 中根据ID得到User表一条记录");
        return null;
    }
}

然后建立一个类库来操作上面建立的User实体类,也就是向User表中添加一条记录,或者通过ID获得一条记录,两个类库操作方法。

public class Test
{
    public static void Main()
    {
        User user=new User();
        SqlServerUser su=new SqlServerUser();
        su.Insert(user);

        su.GetUser(1);

        Console.ReadLine();
    }
}

最后我们通过在控制台程序中进行简单的调用。第一调用插入一条记录,然后通过ID=1获取一条记录。

可以看出,现在的实现非常的简单。那么现在我们来想一个问题。刚刚我们上面的实现是在SQL Server数据库的基础上。那么现在有个需求,是要将现有的数据库SQL Server改为Access数据库的话,我们应该怎么办呢?

SQL Server和Access在ADO.NET上的使用是不同的,在SQL Server上用的是System.Data.SqlClient命名空间下的SqlConnection、SqlCommand、SqlParameter、SqlDataReader、SqlDataAdapter,而Access则要用System.Data.OleDb命名空间下的相应对象,我本以为将其对应的全部替换,局可以使用了,结果替换后,错误百出。

原来两者有不少的地方在使用的时候死不同的。

比如:

1.在插入数据时,Access必须要insert into 而Sql Server可以不用into的;

2.Sql Server中的GetDate()在Access中没有,需要改成Now();

3.Sql Server中字符串含糊Substring,而在Access中根本不能用;

4.这些问题还好了,也不是什么大问题。原来Access对一些关键字,例如password是不能作为数据库的字段的,如果密码的字段名是password,Sql Server 中什么问题都没有,运行正常,在Access中就会报错,而且错误让人莫名其妙。 后来知道了原来关键字应该用‘[’和‘]’包起来,不然当然是容易出错的。

5.主要网站要维护,比如修改或增加一些功能,我们就需要修改两个项目,至少在数据库中做改动,相应的程序代码都要改,甚至和数据库不相干的代码也要改,两个不同的版本,两倍的工作量呀。

6.假如哪天要用Oracle数据库,那又要折腾一阵子了。

现在我们再来分析下刚刚上面的小例子是不能换数据库的,因为就在于SqlServerUser su=new SqlServerUser()使得su这个对象被框死在Sql Server上了。如果这里是灵活的,专业店的说法,是多态的,那么在执行su.Insert(user)和su.GetUser(1)时就不用考虑是在用Sql Server还是在Access。

想一想前面我学习的工厂方法模式,它就是定义一个用于创建对象的接口,让子类决定实例化那一个类。

工厂方法模式来优化数据库访问程序

 先来看一下简单的UML类图关系

看上去很简单,下面我们来用代码实现一下:

IUser接口,用于客户端访问,解除与具体数据库访问的耦合。

    public class User
    {
        public int ID{get;set;}

        public string Name{get;set;}
    }
    interface IUser
    {
        void Insert(User user);

        User GetUser(int id);
    }

在建立接口之前,当然要准备好User类。
接下来完成SqlServerUser和AccesssUser

    public class SqlServerUser:IUser
    {

        public void Insert(User user)
        {
            Console.WriteLine("在SQL Server 中给User表增加一条记录");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在SQL Server 中根据ID得到User表一条记录");
            return null;
        }
    }

    public class AccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在Access中给User表增加一条记录");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在Access中根据ID得到User表一条记录");
            return null;
        }
    }

SqlServerUser类,用于访问Sql Server的User。 AccessUser类,用于访问Access的User。

接下来,建立IFactory接口,定义一个创建访问User表对象的抽象的工厂接口。

    interface IFactory
    {
        IUser CreateUser();
    }

SqlServerFactory类,实现IFactory接口,实例化SqlServerUser.

    public class SqlServerFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new SqlServerUser();
        }
    }

AccessFactory类,实现IFactory接口,实例化AccessUser。

    public class AccessServerFavtory : IFactory
    {
        public IUser CreateUser()
        {
            return new AccessUser();
        }
    }

客户端调用代码

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            IFactory factory = new SqlServerFactory();
            IUser iu=factory.CreateUser();
            iu.Insert(user);
            iu.GetUser(1);
            Console.ReadLine();
        }
    }

 

前言

当然现在只是对一个User表的操作,如果再加一个部门表Department表,该如何处理呢,一个网站,一个项目,不可能只有一个表,会有几十张表,甚至更多,那该如何处理呢,这些问题将会在抽象工厂模式的第二回合进行处理。

时间: 2024-09-19 08:59:31

设计模式之四(抽象工厂模式第一回合)的相关文章

设计模式之四(抽象工厂模式第三回合)

原文:设计模式之四(抽象工厂模式第三回合) 前言 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类,例如IFactory factory=new AccessFactory(),在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置.我们的设计不能去防止需要的变更,那么我们的理想便是让改动变得最小,那么现在如果你要更改数据库访问,

乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) 作者:webabcd 介绍 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例 有Message和MessageModel,Message有一个Insert()方法,该方法的参数是MessageModel. AbstractMessageModel usi

C#设计模式(4)——抽象工厂模式

原文:C#设计模式(4)--抽象工厂模式 一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性.但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是本专

C++设计模式之抽象工厂模式_C 语言

问题描述 之前讲到了C++设计模式--工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理:由于工厂方法模式创建的对象都是继承于Product的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的产品(不继承自Product)时,发现工厂方法是心有余而力不足. 举个例子来说:一个显示器电路板厂商,旗下的显示器电路板种类有非液晶的和液晶的:这个时候,厂商建造两个工厂,工厂A负责生产非液晶显示器电路板,工厂B负责生产

.NET简谈设计模式之(抽象工厂模式)

我们继续学习设计模式系列文章. 今天要讲的是设计模式中经常被用到的"工厂模式",所谓工厂模式就是将对象的创建交给一个叫做工厂的对象来统一进行处理.主要是将对象的依赖关系进行解耦,消除对象之间的直接耦合.那么工厂的使用有几种方式呢?那就要看我们对工厂的理解了,工厂是创建对象的一个逻辑名称,工厂可以是一个方法.一个静态类等等.只要起到对象的创建就能给它赋予上一个工厂的名称. 那么什么是抽象工厂呢?我想很多人对它的理解并不是很透彻,甚至有的人就觉得工厂一定要是抽象的.我表示不理解,一个抽象类

设计模式之抽象工厂模式

关于设计模式找到了一个系列讲的非常到位,也很容易让人理解,这里我也是看下面的博客来理解抽象工厂模式. http://blog.csdn.net/column/details/loveyun.html?&page=2 理解抽象工厂应先了解产品族.产品等级的概念: 所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族.比如AMD的主板.芯片组.CPU组成一个家族,Intel的主板.芯片组.CPU组成一个家族.而这两个家族都来自于三个产品等级:主板.芯片组.CPU.一个等级结构是由相同的

Python设计模式之抽象工厂模式_python

python面向对象编程入门,我们需要不断学习进步 """抽象工厂模式的实现""" import random class PetShop: """宠物商店""" def __init__(self, animal_factory=None): """宠物工厂是我们的抽象工厂.我们可以随意设置.""" self.pet_fact

艾伟_转载:.NET设计模式:抽象工厂模式(Abstract Factory)

概述 在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作:同时由于需求的变化,往往存在着更多系列对象的创建工作.如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种"封装机制"来避免客户程序和这种"多系列具体对象创建工作"的紧耦合?这就是我们要说的抽象工厂模式. 意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 模型图 逻辑模型: 物理模型: 生活中的例子 抽象工厂的目的是要提供一个创建一系列相关或

Head First设计模式之抽象工厂模式

一.定义 给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件:     1)系统中有多个产品族,而系统一次只可能消费其中一族产品.      2)同属于同一个产品族的产品以其使用.  二.结构 抽象工厂模式的各个角色(和工厂方法一样):      1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.      2)具体工厂角色:它含有和具体业务逻辑有关的代码.