zoukankan      html  css  js  c++  java
  • 设计模式之四(抽象工厂模式第一回合)

    前言

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

    第一回合  

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

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

    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表,该如何处理呢,一个网站,一个项目,不可能只有一个表,会有几十张表,甚至更多,那该如何处理呢,这些问题将会在抽象工厂模式的第二回合进行处理。

  • 相关阅读:
    Windows下安装使用OpenLDAP
    LDAP安装配置(windows)
    LDAP概念和原理介绍
    JDK自带的keytool证书工具详解
    递归算法讲解
    Creating an archive from a directory without the directory name being added to the archive
    Overview of the M&A Process
    Make sure base method gets called in C#
    How to delete specific nodes from an XElement?
    如何学习数据结构?
  • 原文地址:https://www.cnblogs.com/aehyok/p/3087497.html
Copyright © 2011-2022 走看看