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

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 原文:设计模式之四(抽象工厂模式第一回合)前言 首先关于抽象工厂模式的学习,我们需要慢慢的,由浅入深的进入。不能单刀直入,否则可能达不到预期学明白的目标。 第一回合    首先我们从最简单的数据访问程序开始吧。
原文: 设计模式之四(抽象工厂模式第一回合)

前言

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

第一回合  

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

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

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

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
4月前
|
设计模式 Java
Java设计模式【三】:抽象工厂模式
Java设计模式【三】:抽象工厂模式
21 0
|
6天前
|
设计模式 Java
【设计模式系列笔记】抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是一种设计模式,属于创建型模式之一。它提供了一种方式来创建一系列相关或相互依赖的对象,而无需指定它们具体的类。抽象工厂模式通过引入抽象的工厂接口,使得客户端代码可以使用抽象的接口来创建一组相关的产品,而不关心这些产品的具体实现。
101 4
|
22天前
|
设计模式 Java Windows
23种设计模式,抽象工厂模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】抽象工厂模式是一种创建型设计模式,它提供了一个接口用于创建相关或依赖对象的家族,而不需要指定具体类。该模式允许客户端在不知道具体类的情况下,通过其共同的接口来创建一组产品。
29 7
|
3月前
|
设计模式 Oracle 关系型数据库
设计模式 | 抽象工厂模式
设计模式 | 抽象工厂模式
25 0
|
3月前
|
设计模式 Go 开发工具
Golang设计模式——02抽象工厂模式
Golang设计模式——02抽象工厂模式
23 0
|
3月前
|
设计模式 前端开发
【设计模式】之抽象工厂模式
抽象工厂模式是一种创建型设计模式,适用于需要创建一系列相关或相互依赖对象的场景。在前端开发中,抽象工厂模式可以帮助我们更好地组织和管理代码,提高代码的可维护性和可扩展性。它通过封装对象的创建过程,使得客户端代码与具体类解耦,并且可以通过切换具体工厂类来改变整个系统的行为。然而,它也增加了系统的复杂度,并且当产品族较多时会导致大量的具体工厂类。因此,在使用抽象工厂模式时需要权衡利弊,并根据实际情况进行选择。
54 0
【设计模式】之抽象工厂模式
|
3月前
|
设计模式 NoSQL 中间件
设计模式 - 创建型模式_抽象工厂模式
设计模式 - 创建型模式_抽象工厂模式
23 0
|
4月前
|
设计模式
二十三种设计模式全面解析-抽象工厂模式:创造无限可能的工厂之道
二十三种设计模式全面解析-抽象工厂模式:创造无限可能的工厂之道
|
4月前
|
设计模式 SQL 数据库连接
设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)
设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)
|
5月前
|
设计模式 Java Maven
你不能不了解的Java23中设计模式之【抽象工厂模式】
你不能不了解的Java23中设计模式之【抽象工厂模式】