删除对象的设计模式?

时间:2016-10-12 08:37:17

标签: .net vb.net oop design-patterns

假设我有一个存储在数据库中的对象(在下面的例子中,类Aggregation)。如果我想删除它,运行.Delete()似乎是显而易见的方法。

调用此方法时,我当前的方法是将其从数据库中删除,然后在调用它的代码中销毁该对象。但是这感觉不对 - 如果调用它的代码实际上没有破坏对象会发生什么。然后可能发生各种不一致。

一条路由是在调用.Delete()时设置标志,然后在运行任何其他函数或子例程之前检查此标志。但是有更漂亮的方式吗?

很抱歉提出这个问题 - 我觉得它应该更加明显,但谷歌搜索没有帮助。

Imports System.Data.SqlClient

Public Class Aggregation

    Public ReadOnly Property ID As Integer
    Public ReadOnly Property Name As String

    Private Sub New(ID As Integer, name As String)
        Me.ID = ID
        Me.Name = name
    End Sub

    Public Shared Function CreateNew(Name As String) As Aggregation
        Dim query As String = "INSERT INTO TRAF_AGGREGATION (NAME) VALUES (@NAME); SELECT SCOPE_IDENTITY();"
        Using cmd As New SqlCommand(query)
            cmd.Parameters.AddWithValue("@NAME", Name)

            Dim result As DataTable = Core._dm.ExecuteQuery(cmd)
            Return New Aggregation(result.Rows(0).Item(0), Name)
        End Using
    End Function

    Public Shared Function Load(AggregationID As Integer) As Aggregation
        Dim query As String = "SELECT * FROM AGGREGATION WHERE ID = @ID;"
        Using cmd As New SqlCommand(query)
            cmd.Parameters.AddWithValue("@ID", AggregationID)
            Dim result As DataTable = Core._dm.ExecuteQuery(cmd)
            If result.Rows.Count = 0 Then
                Throw New ArgumentOutOfRangeException("AggregationID", AggregationID, "No aggregation with this ID")
            Else
                Return New Aggregation(AggregationID, result(0)("NAME"))
            End If
        End Using
    End Function

    Friend Sub Rename(newName As String)
         ...
    End Sub

    ....

    Friend Sub Delete()
        Dim query As String = "DELETE FROM AGGREGATION WHERE ID = @ID;"
        Using cmd As New SqlCommand(query)
            cmd.Parameters.AddWithValue("@ID", ID)
            Core._dm.ExecuteNonQuery(cmd)
        End Using
        _ID = -1
    End Sub
End Class

1 个答案:

答案 0 :(得分:0)

正如Alex B.建议的那样,最好的解决方案是使用 ORM 来处理所有这些复杂性。

但如果你没有或者你不能使用它,我认为更好的方法可能是:

  1. 从您的实体类(聚合)中删除所有CRUD方法
  2. 定义一种 Controller ,它在您的实体类上实现CRUD方法并返回适当的结果事件/对象
  3. 定义一种 ConnectionFactory ,它将处理与数据库的连接并管理各种会话
  4. 定义 EntityMapper ,将查询结果映射到您的实体,反之亦然
  5. 定义 QueryUtils ,它将处理以可重用方式构建的所有低级sql语法和标准
  6. 回到你的问题,重点是你执行行动的顺序:

    1. 首先执行查询,执行此操作的对象(或驱动程序)将返回结果或异常
    2. 您处理结果或例外
    3. 如果一切正常,那么您可以更新实体状态或从应用程序上下文中删除
    4. 希望这可以帮到你!