2009-10-26 115 views
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经典 - 不恨球员,讨厌游戏 - 但你是如何解决在任何语言中这个问题我很感兴趣)

回答

1

IMO你不要在这里重复自己。在CanViewOrder业务逻辑是不一样的GetOrders业务逻辑。有一种肤浅的相似之处,这是事实,但这两条规则在理论上可以有不同的演变。

1

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

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

然后避免通过实施GetOrders(user)如超过设定的订单将CanView(user, order)过滤重复的访问策略。

已经走了这条路线,你可以定义其他的“查询”,也一劳永逸,独立政策的方式,以及它如何可能会改变。例如:GetUsersWhoCanView(order)CanViewSameOrders(user1, user2)CanAnybodyView(order) ...

对于只有少数依靠它,“直接的方式”功能的简单和相对静态的政策,有据可查,为您提供最佳效率和最头痛。如果您的政策可能变得复杂或者可能经常改变,或者将来可能会被许多其他功能使用,那么使用上面列出的模块化方法可以避免产生技术债务。