这是一个很好的问题
design-patterns
具有
VBA
.
完整的描述
strategy pattern
可见
here
,但总而言之,这是一个描述它的UML类和序列图:
基本上,这种策略允许算法独立于使用它的客户机而变化。
将使用哪个算法的决定推迟到运行时,可以使调用代码更加灵活和可重用。
你提出了这两个解决方案,我想解释一下为什么我没有使用它们:
-
包装
DatabaseStrategy
围绕特定于记录和应用程序的记录(
DatabaseStrategy.Create(Record).Save
使用这种溶液会减少
cohesion
,因为
class
数据库策略必须负责实例化
Record
objects
(如我稍后所述,这可以通过应用来完成
Factory-Pattern
)
-
战略数据库
作为记录中的一员,但应用程序似乎必须知道这一点
战略数据库
是记录的成员(
Record.DatabaseStrategy.Save
)
这种设计模式必须知道策略,但创新之处在于它可以在运行时更改,传递实现动作方法的设计策略对象。在这种情况下,我会搬家
战略数据库
记录
最后一次提到是因为
object
Database
我稍后会展示)。
物体
班
不接受参数的构造函数,我使用了另一种模式:
Factory Pattern
下面的代码只是为了说明如何使用这两种模式,因此省略了许多函数,并且没有实际的数据库方法实现。下面是剩下的代码:
IRecord公司
班
(
接口
):
Public Function getValue() As String: End Function
Public Function setValue(stringValue As String): End Function
班
这个类基本上代表一个数据库记录。简单来说,我们只有一个
value
属性,但实际实现当然会有所不同。
Implements IRecord
Private value As String
Private Function IRecord_getValue() As String
IRecord_getValue = value
End Function
Private Function IRecord_setValue(stringValue As String)
value = stringValue
End Function
i连接策略
班
(
这是连接策略的接口。这里的代码没有什么变化。
Public Function Save(ByVal record As IRecord): End Function
班
类中的Strategy A。这里的代码有一点变化。
Implements IConnectionStrategy
Private connectionString As String
Private Sub Class_Initialize()
connectionString = "DRIVER=Oracle Server;SERVER=myA.server.com\DatabaseA;"
End Sub
'Implements Strayegy A
Private Function IConnectionStrategy_Save(ByVal record As IRecord)
Debug.Print "Saving to ", connectionString, "Record with value:", record.getValue
End Function
连接策略
班
类中的Strategy A。这里的代码有一点变化。
Implements IConnectionStrategy
Private connectionString As String
Private Sub Class_Initialize()
connectionString = "DRIVER=SQL Server;SERVER=myB.server.com\DatabaseB;"
End Sub
'Implements Strategy B
Private Function IConnectionStrategy_Save(ByVal record As IRecord)
Debug.Print "Saving to ", connectionString, "Record with value:", record.getValue
End Function
班
这是处理与数据库连接的类。连接策略定义了如何连接到数据库。
setConnectionStrategy(...)
Private connection As IConnectionStrategy
Private Sub Class_Initialize()
'Initialize everything but strategy.
End Sub
'Funzione che verrà richiamata per inizializzare le propietà della classe
Public Sub InitiateProperties(ByVal connectionStrategy As IConnectionStrategy)
Set connection = connectionStrategy
End Sub
Public Sub saveRecord(ByVal record As IRecord)
connection.Save record
End Sub
Public Sub setConnectionStrategy(ByVal strategy As IConnectionStrategy)
connection = strategy
End Sub
Private Sub Class_Terminate()
'close connections
End Sub
数据库工厂
Module
(VBA没有静态类,因此请改用模块)
Database Objects
'Instantiate a Database with given Strategy
Public Function createDatabaseWithStrategy(strategy As IConnectionStrategy) As Database
Set createDatabaseWithStrategy = New Database
CreateFoglioIdro.InitiateProperties connectionStrategy:=strategy
End Function
'Instantiate a Database with Strategy A
Public Function createDatabaseWithStrategyA() As Database
Set createDatabaseWithStrategyA = New Database
createDatabaseWithStrategyA.InitiateProperties connectionStrategy:=New ConnectionStrategyA
End Function
'Instantiate a Database with Strategy B
Public Function createDatabaseWithStrategyB() As Database
Set createDatabaseWithStrategyB = New Database
createDatabaseWithStrategyB.InitiateProperties connectionStrategy:=New ConnectionStrategyB
End Function
App Module
):
Option Explicit
Public Sub ApplicationA()
Dim record As IRecord
Set record = New record
record.setValue ("This is a value")
Dim db As Database
Set db = DatabaseFactory.createDatabaseWithStrategyA
db.saveRecord record
'Prints-> Saving to DRIVER=Oracle Server;SERVER=myA.server.com\DatabaseA; Record with value: This is a value
End Sub
Public Sub ApplicationB()
Dim record As IRecord
Set record = New record
record.setValue ("This is a value")
Dim db As Database
Set db = DatabaseFactory.createDatabaseWithStrategyB
db.saveRecord record
'Prints-> Saving to DRIVER=SQL Server;SERVER=myB.server.com\DatabaseB; Record with value: This is a value
End Sub
如你所见,
strategy-pattern
与
,帮助您消除初始化数据库和为数据库设置策略所需的大部分重复代码
.