如何设计阶级关系。他们应该知道自己吗?

时间:2014-03-21 08:32:27

标签: vb.net oop architecture

这一切都在vb.net中完成

我有一个班级" INVOICE"和一个班级"装运"

发票类有一个SHIPMENTS属性(发货类列表),所以我可以编写如下代码:

dim inv as new Invoice
dim ship as new Shipment
inv.shipments.add(ship)

现在货运类可以没有发票类。它用于应用程序的其他部分,它不属于"任何发票。

现在很多时候我发现自己需要参考我作为参数传递的货件的发票。 我想写一些例子:

Private Sub SetUpLabels(ship as Shipment)
    lblInvoice.Text = ship.Invoice.Number
    lblShipmentDestination.Text = ship.Destination
End Sub

实现目标的正确方法是什么?

我有一种感觉我不应该将INVOICE作为SHIPMENT类的属性添加 在这种情况下,我是否应该将INVOICE和SHIPMENT作为参数传递 像这样的东西?

Private Sub SetUpLabels(ship as Shipment, inv as Invoice)
    lblInvoice.Text = inv.Number
    lblShipmentDestination.Text = ship.Destination
End Sub

2 个答案:

答案 0 :(得分:0)

听起来你已经做得很好了。您可能希望更进一步,并设计一个类InvoiceShipment,使用Shipment类型的属性扩展Invoice

dim inv as new Invoice

dim ship as new InvoiceShipment

inv.shipments.add(ship) 

ship.Invoice = inv

class diagram

答案 1 :(得分:0)

除了Steven Liekens的回答之外,还有其他一些选择。

InvoiceShipment

使用某种装饰器
Class InvoiceShipment
    Public Property DecoratedShipment As Shipment 
    Public Property Invoice As Invoice
End Class

然后

Class Invoice
    Private shipments As List(Of InvoiceShipment)
    Public Sub AddShipment(s As Shipment)
        shipments.Add(New InvoiceShipment With {.Invoice = Me, .DecoratedShipment = s})
    End Sub

    'If you just need the plain invoices
    Iterator Function GetShipments() As IEnumerable(Of Shipment)
        For Each s As InvoiceShipment In shipments
            Yield s.DecoratedShipment
        Next
     End Function

另一种方法是使用扩展方法:

Imports System.Runtime.CompilerServices
Module ShipmentExtensions

    Dim invoiceMapping As New ConditionalWeakTable(Of Shipment, Invoice)

    <Extension()>
    Public Function GetInvoice(ByVal shipment As Shipment) As Invoice
        Dim invoice As Invoice
        If Not invoiceMapping.TryGetValue(shipment, invoice) Then
            Return Nothing
        End If
        Return invoice
    End Function

    <Extension()>
    Public Sub SetInvoice(shipment As Shipment, invoice As Invoice)
        invoiceMapping.Add(shipment, invoice)        
    End Sub

    <Extension()>
    Public Sub UnsetInvoice(shipment As Shipment)
        invoiceMapping.Remove(shipment)
    End Sub
End Module

然后在Invoice课程中,您只需设置发票:

Class Invoice 
   ...
   Public Sub AddShipment(ByVal shipment As Shipment)
       ...
       shipment.SetInvoice(Me)
   End Sub

您可以通过anyShipment.GetInvoice()随时访问发票。请注意,如果没有关联Nothing,则可能会返回Invoice

这种方法是某种混合物,它意识到货物可能扮演角色ShipmentInInvoice这一事实。但建模动态角色非常困难。因此,这是一个静态的角色。