Можно ли ограничить создание объекта только одним другим (родительским) объектом в VB.NET? - PullRequest
2 голосов
/ 27 апреля 2010

VB 2008 .NET 3.5

Предположим, у нас есть два класса, Order и OrderItem, которые представляют некоторый тип системы онлайн-заказов. OrderItem представляет отдельную позицию в заказе. Один заказ может содержать несколько элементов OrderItem в форме списка (элемента OrderItem).

Public Class Order
    Public Property MyOrderItems() as List(of OrderItem)
    End Property
End Class

Имеет смысл, что OrderItem не должен существовать без Order. Другими словами, класс OrderItem не должен иметь возможность создавать его самостоятельно, он должен зависеть от класса Order, который будет содержать его и создавать его экземпляр. Однако OrderItem должен быть открытым по объему, чтобы его свойства были доступны другим объектам. Итак, требования для OrderItem:

  1. Может быть создан только классом Order.

  2. Должен быть общедоступным, чтобы любой другой объект мог получить доступ к его свойствам / методам через объект Order. например Order.OrderItem (0) .ProductID.

  3. OrderItem должен иметь возможность передаваться другим подпрограммам / функциям, которые будут работать с ним.

Как мне достичь этих целей? Есть ли лучший подход?

Ответы [ 3 ]

4 голосов
/ 27 апреля 2010

Вы можете создать один конструктор из OrderItem, который будет принимать элемент Order.

В этом конструкторе вы можете добавить OrderItem в коллекцию Order.MyOrderItems.

Это удовлетворит ваши требования.

Public Class OrderItem
    Public Sub New(ByRef myOrder As Order)
        myOrder.MyOrderItems.Add(Me)
    End Sub
End Class
  1. Вы можете создать экземпляр OrderItem, только передав ему действительный Order объект.
  2. Все еще общедоступен и может вызываться по мере необходимости (Order.OrderItem(0).ProductID).
  3. OrderItem может быть передан другим подпрограммам и функциям.
3 голосов
/ 28 апреля 2010

Стандартный способ сделать это - представить OrderItem в качестве интерфейса, а затем реализовать его в закрытом классе внутри класса Order. Класс OrderItem может быть создан только внутри класса Order, но он может быть открыт извне через открытый интерфейс IOrderItem. Вот так:

Public Interface IOrderItem
    ReadOnly Property ItemCode() As Integer
    ReadOnly Property NumberOfItems() As Integer
    ReadOnly Property Description() As String
End Interface

Public Class Order

    Private m_Items As List(Of IOrderItem)

    Public ReadOnly Property Items() As List(Of IOrderItem)
        Get
            Return m_Items
        End Get
    End Property

    Private Class OrderItem
        Implements IOrderItem

        Private m_Code As Integer
        Private m_NumItems As Integer
        Private m_Description As String

        Public Sub New(ByVal code As Integer, ByVal numItems As Integer, ByVal desc As String)
            m_Code = code
            m_NumItems = numItems
            m_Description = desc
        End Sub

        Public ReadOnly Property Description() As String Implements IOrderItem.Description
            Get
                Return m_Description
            End Get
        End Property

        Public ReadOnly Property ItemCode() As Integer Implements IOrderItem.ItemCode
            Get
                Return m_Code
            End Get
        End Property

        Public ReadOnly Property NumberOfItems() As Integer Implements IOrderItem.NumberOfItems
            Get
                Return m_NumItems
            End Get
        End Property
    End Class
End Class
2 голосов
/ 27 апреля 2010
Конструктор

OrderItem должен быть friend (доступен только для Order) - я говорю friend, потому что с помощью friend вы можете ограничить видимость конструктора OrderItem для классов в такая же сборка. Примечание : это решение подразумевает, что Order и OrderItem находятся в одной библиотеке / сборке, а вы пытаетесь использовать их из другой сборки - в противном случае защита friend не работает.

Ответственность за создание OrderItem объектов должна принадлежать только Order:

Создайте метод, подобный классу Order: Public Function CreateOrderItem(whateverParametersYouNeed) as OrderItem, который внутренне создает новый экземпляр OrderItem, добавляет его в список OrderItem и возвращает ссылку на вновь созданный элемент.

Затем вы можете делать все, что захотите, с этим OrderItem - он всегда будет принадлежать списку Order.

...