admin管理员组

文章数量:1442409

设计模式:适配器模式(Adapter)(1)

这应该是设计模式系统的第一篇。

VFP 开发人员似乎对“设计模式”这个概念不是很熟悉,可能偶尔在某个高人那里听那么一两耳朵。这个系列希望从 VFP 的角度来认识它们,并可以运用到 C#/X# 的应用设计。

--------------------------------------------------------

场景一:从零开始的开发

需求:建立和 SQL Server 的连接

我相信最大多数 foxer 的一开始的写法一定是这样的:

代码语言:javascript代码运行次数:0运行复制
Local cConnectString As String, nStatementHandle As Number
m.cConnectString	= "Driver={SQL Server};UID=sa;PWD=你的密码;Server=你的IP地址;Database=你的数据库"
m.nStatementHandle	= Sqlstringconnect(m.cConnectString, .T.)

整个系统中,不可避免的存在某些基础资料。如果在部署时人工填入,无论对于哪一方来说,都是不小的负担,况且,甲方爸爸一句“我们的人计算机水平不行,也没你熟悉,还是你来录入吧”,然后扔给你一个格式“不规范”的电子表格,镜头一转,就只剩你独自一人在风中凌乱......

然后,你也不想大力出奇迹,那是大力水手的事儿......你开始琢磨怎么能从电子表格把基础数据导入到你的系统中。

然后不可避免的情况发生了,修改已有的代码,在需要导入的位置添加代码以建立和电子表格的连接,然后是导入的代码......如果你对该领域不熟悉,就进入一行代码十个问题的阶段......然后会发出感慨:雷锋都死绝了!

终于,代码完成了。你长舒了一口气......终于干完了......然后,泡上一杯茶,点上一支烟,悠哉游哉......忽然,你似乎意识到,它和建立到 SQL Server 的连接在本质上有什么不同吗?然后你看着你凌乱的代码,默默的对自己说:“哎,赶时间,现在只能是这样,等有时间再改吧”......日复一日,屎山逐渐成型,技术债务越积越多......“明日复明日,明日何其多,万事待明日,一切成蹉跎。”当你要让自己退休的时候,不知道你会不会想起明日歌......

好像扯远了哈......

有人会觉得我说的过于奇葩,“这些难道不是刚入门的人常犯的错误吗?像我等这样写了几十年VFP代码的人怎么会出现这样低级的问题?”虽然我没有写几十年VFP的代码,但是我也是这样想滴。直到我第一次真正开始对“设计模式”有兴趣的时候,我才发现,自己竟是如此的浅薄......

让我们走进时光机,回到问题的最初时刻......你看着独自在风中凌乱的自己,告诉他:“别害怕,我来告诉你办法。”

在你需要建立连接的地方,使用一个连接类。现在是电子表格,以后可能是 Access 数据库,亦或其他什么玩意儿,这个连接类通吃。

代码语言:javascript代码运行次数:0运行复制
*** <summary>
*** 通用连接类
*** </summary>
*** <remarks>这在适配器模式中称为适配器(Adapter)</remarks>
Define Class myConnect as Custom
	*** <summary>
	*** 连接方法
	*** </summary>
	*** <param name="toConnect">负责连接各种数据库的连接对象实例</param>
	*** <remarks>在方法中调用连接对象的 CreatConnect 方法返回连接句柄</remarks>
	Procedure CreatConnect(toConnect As Object) as Number
		Return m.toConnect.CreatConnect()
	EndProc
EndDefine

那么,你原来的代码就可以修改成像这样:

代码语言:javascript代码运行次数:0运行复制
Local oSQLServer as Object, oConnect as myConnect, nStatementHandle As Number
m.oSQLServer	= NewObject("SQLServer")
m.oConnect	= NewObject("myConnect")

m.nStatementHandle	= m.oConnect.CreatConnect(m.oSQLServer)

在创建 SQLServer 连接类之前,我们先创建一个模板类:

代码语言:javascript代码运行次数:0运行复制
*** <summary>
*** 连接对象的模板类
*** <summary>
*** <remarks>
*** <para>这种模板类,在 .NET 语言中称之为接口</para>
*** <para>接口(Interface)名称通常以字母 I 开头</para>
*** </remarks>
Define Class IConnect As Custom
	*** <summary>
	*** 模板的 CreatConnect 方法
	*** </summary>
	*** <returns>数值型,表示连接句柄</returns>
	*** <remarks>这是一个空方法,所有集成自该模板类的子类需要实现此方法</remarks>
	Procedure CreatConnect() As Number
	Endproc
EndDefine

派生此模板,完成 SQLServer 类的定义

代码语言:javascript代码运行次数:0运行复制
*** <summary>
*** SQL Server 连接类
*** </summary>
Define Class SQLServer as IConnect
	*** <summary>
	*** 建立数据库连接的具体实现方法
	*** </summary>
	*** <param name="toConnect">负责连接各种数据库的连接对象实例</param>
	*** <returns>数值型,表示连接句柄</returns>
	*** <remarks>这是一个空方法,所有集成自该模板类的子类需要实现此方法</remarks>
	Procedure CreatConnect() As Number
		Local cConnectString As String, nStatementHandle As Number
		m.cConnectString	= "Driver={SQL Server};UID=sa;PWD=你的密码;Server=你的IP地址;Database=你的数据库"
		m.nStatementHandle	= Sqlstringconnect(m.cConnectString, .T.)

		Return m.nStatementHandle
	Endproc
EndDefine

然后,依葫芦画瓢,创建 Excel 类,并在需要和 Excel 建立连接的地方,有模有样的抄自己之前的代码:

代码语言:javascript代码运行次数:0运行复制
Local oExcel as Object, oConnect as myConnect, nStatementHandle As Number
m.oExcel	= NewObject("Excel")
m.oConnect	= NewObject("myConnect")

m.nStatementHandle	= m.oConnect.CreatConnect(m.oExcel)

好了,置于以后需要再连接XXX数据库,你就再建一个派生自 IConnect 类的 XXX 类就 OK 了。

如果说之前的代码是河南大乱炖,那么,现在,应该算是正宗的豫菜了。

在后续发表之前,你有足够的时间慢慢体会......

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-01,如有侵权请联系 cloudcommunity@tencent 删除数据库adapter对象连接设计模式

本文标签: 设计模式适配器模式(Adapter)(1)