代码之家  ›  专栏  ›  技术社区  ›  Victor K

类方法的特定于应用程序的实现

  •  5
  • Victor K  · 技术社区  · 7 年前

    Save 方法,该类
    为了解决这个问题,我尝试使用一种策略模式(我可能误解了这个模式),但是我对这个主题的理解还不够。在运行时,我提供一个策略类来处理保存。公共类公开 保存

    IRecord(公共类)接口:

    Public Function DoSomething(): End Function
    Public Function SetStrategy(ByVal Strategy As IDatabaseStrategy): End Function
    

    记录(公共类)实现:

    Private RecordStrategy As IDatabaseStrategy
    Implements IRecord
    Implements IDatabaseStrategy 'Implements this interface to have Save method
    Private Function IRecord_DoSomething():
        'does whatever the class is supposed to do
    End Function
    Private Function IRecord_SetStrategy(ByVal Strategy As IDatabaseStrategy)
        Set RecordStrategy = Strategy
    End Function
    Private Function IDataBaseStrategy_Save()
        RecordStrategy.Save
    End Function
    

    战略接口与实施:

    • IDatabaseStrategy公司: Public Function Save():End Function

    • 数据库策略a:

      Implements IDatabaseStrategy
      Private Function IDataBaseStrategy_Save()
      Debug.Print "Saving to database A"
      End Function
      
    • 数据库策略B:

      Implements IDatabaseStrategy
      Private Function IDataBaseStrategy_Save()
      Debug.Print "Saving to database B"
      End Function
      

    Option Explicit
    
    Public Sub ApplicationA()
        Dim Item As IRecord
        Set Item = New Record
        Dim Strategy As IDatabaseStrategy
        Set Strategy = New DatabaseStrategyA
        Item.SetStrategy Strategy 'this would normally be done with constructor
        Dim ItemToSave As IDatabaseStrategy
        Set ItemToSave = Item
        ItemToSave.Save
    End Sub
    
    Public Sub ApplicationB()
        Dim Item As IRecord
        Set Item = New Record
        Dim Strategy As IDatabaseStrategy
        Set Strategy = New DatabaseStrategyB
        Item.SetStrategy Strategy 'this would normally be done with constructor
        Dim ItemToSave As IDatabaseStrategy
        Set ItemToSave = Item
        ItemToSave.Save
    End Sub
    

    Record Database strategy 拥有 方法,然后重铸 Item IRecord IDatabaseStrategy DatabaseStrategy 到a 记录 这样我就不必重新构造对象,而且可能还没有实现 在里面 记录 我考虑过的备选方案:

    • 包装 战略数据库 记录 记录 以及应用程序( DatabaseStrategy.Create(Record).Save )
    • 暴露 战略数据库 记录 但应用程序似乎必须知道这一点 战略数据库 是记录的成员( Record.DatabaseStrategy.Save ).
    0 回复  |  直到 7 年前
        1
  •  2
  •   Louis    7 年前

    这是一个很好的问题 design-patterns 具有 VBA .

    完整的描述 strategy pattern 可见 here ,但总而言之,这是一个描述它的UML类和序列图:

    enter image description here

    基本上,这种策略允许算法独立于使用它的客户机而变化。

    将使用哪个算法的决定推迟到运行时,可以使调用代码更加灵活和可重用。

    你提出了这两个解决方案,我想解释一下为什么我没有使用它们:

    • 包装 DatabaseStrategy 围绕特定于记录和应用程序的记录( DatabaseStrategy.Create(Record).Save

      使用这种溶液会减少 cohesion ,因为 class 数据库策略必须负责实例化 Record objects (如我稍后所述,这可以通过应用来完成 Factory-Pattern )

    • 战略数据库 作为记录中的一员,但应用程序似乎必须知道这一点 战略数据库 是记录的成员( Record.DatabaseStrategy.Save )

      这种设计模式必须知道策略,但创新之处在于它可以在运行时更改,传递实现动作方法的设计策略对象。在这种情况下,我会搬家 战略数据库 记录 最后一次提到是因为 object Database 我稍后会展示)。

    物体 不接受参数的构造函数,我使用了另一种模式: Factory Pattern

    enter image description here

    下面的代码只是为了说明如何使用这两种模式,因此省略了许多函数,并且没有实际的数据库方法实现。下面是剩下的代码:

    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 ,帮助您消除初始化数据库和为数据库设置策略所需的大部分重复代码 .

    推荐文章