0

好的。所以这是我的简化方案。我们有一个系统可以处理许多客户的订单。我们希望员工用户能够查看所有订单,我们希望客户用户只能查看与其相关的订单。

当尝试查看特定记录时,我们在 OrderSecurity 类中使​​用以下函数:

Public Function CanViewOrder(order)
    If currentUser.MemberOfStaff() Then
        CanViewOrder = True
    Else
        CanViewOrder = (order.ClientId = currentUser.ClientId)
    End If
End Function

当我们想要向用户显示订单列表时,我们可以在 OrderService 类中定义以下函数

Public Function GetOrders()
    If currentUser.MemberOfStaff() Then
        GetOrders = GetAllOrders()
    Else
        GetOrders = GetAllOrdersForClient(currentUser.ClientId)
    End If
End Function

这对上述情况来说是可以的,但随着规则变得更加复杂,这并不能很好地维持。比如说,我们添加了另一种用户类型,它代表了一个不太受信任的员工,他只能查看来自客户子集的订单。然后,我们必须向 CanViewOrder 和 GetOrders 函数(可能在数据访问类中)添加逻辑,这在我看来违反了 DRY 原则。

所以,我的问题是:我是否在这里遗漏了一个技巧 - 是否有某种方法可以组合业务逻辑以获得在一个地方查看订单的权限,这两个功能都可以使用?

还是我太担心了,应该继续前进,在两个地方都有逻辑?

(在这个特定的应用程序中,我使用的是 ASP Classic - 不要讨厌播放器,讨厌游戏 - 但我会对你如何用任何语言解决这个问题感兴趣)

4

2 回答 2

1

IMO,您不会在这里重复自己。中的业务逻辑CanViewOrder与 中的业务逻辑不同GetOrders。有表面上的相似之处,这是真的,但从理论上讲,这两条规则可能会发生不同的演变。

于 2009-10-26T17:06:01.513 回答
1

您可以集中访问策略并使其更通用(可能以牺牲效率为代价),方法是将其保留在您拥有的谓词中,只是稍微概括一下以考虑主题(用户)和对象(顺序):

Public Function CanView(user, order)
    (magic)
End Function

GetOrders(user)然后通过实施作为应用于CanView(user, order)一组订单的过滤器来避免重复您的访问策略。

走这条路后,您也可以一劳永逸地定义其他“查询”,其方式独立于政策及其可能发生的变化。例如:GetUsersWhoCanView(order), CanViewSameOrders(user1, user2), CanAnybodyView(order),...

对于只有少量函数依赖的简单且相对静态的策略,有据可查的“直接方法”可为您提供最佳效率和最少麻烦。如果您的策略可能变得复杂或可能经常更改,或者将来可能最终被许多其他功能使用,那么使用我上面概述的模块化方法可以避免产生技术债务。

于 2009-10-27T14:00:55.740 回答