2010-04-27 5 views
2

VB 2008 .NET 3.5VB.NET에서 개체의 인스턴스화를 다른 (부모) 개체로만 제한 할 수 있습니까?

온라인 주문 시스템의 일부 유형을 나타내는 Order와 OrderItem의 두 클래스가 있다고 가정합니다. OrderItem은 주.의 단일 행 항목을 나타냄니다. 하나의 주.에는 OrderItem의 List 양식으로 여러 OrderItem을 포함 할 수 있습니다.

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

주문이 없으면 OrderItem이 없어야합니다. 즉, OrderItem 클래스는 자체적으로 인스턴스화 할 수 없어야하며 OrderItem 클래스를 포함하고 인스턴스화해야하는 Order 클래스에 종속되어야합니다. 그러나 OrderItem은 다른 오브젝트에서 속성에 액세스 할 수 있도록 범위가 공개되어야합니다. OrderItem의 요구 사항은 다음과 같습니다.

  1. Order 클래스에서만 인스턴스화 할 수 있습니다.

  2. 다른 개체가 Order 개체를 통해 다른 개체의 속성/메서드에 액세스 할 수 있도록 공개이어야합니다. 예 : Order.OrderItem (0) .ProductID.

  3. OrderItem이 작동 할 다른 하위/함수로 전달 될 수 있어야합니다.

어떻게 이러한 목표를 달성 할 수 있습니까? 더 나은 접근 방법이 있습니까?

답변

3

표준적인 방법은 OrderItem을 인터페이스로 노출 한 다음 Order 클래스 내부의 개인 클래스에 구현하는 것입니다. OrderItem 클래스는 Order 클래스 내에서만 인스턴스화 될 수 있지만 public 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 
+0

이것은 제가 본 가장 우아한 해결책입니다. 나는 이것을 수행하기 위해 어떤 유형의 언어 구조가 있었으면 좋겠다. 나는 집계/복합 클래스를 많이 사용한다. –

+0

그런 선언은 어셈블리가'IOrderItem'을 구현할 수는 없지만 적합하다고 생각하고, 그러한 구현을 'OrderItem'과 같은 방식으로 구현 될 것으로 예상되는 순진한 코드에 전달하겠습니까? – supercat

4

OrderItem의 단일 생성자를 Order 항목으로 만들 수 있습니다.

이 생성자에서 OrderItemOrder.MyOrderItems 컬렉션에 추가 할 수 있습니다.

귀하의 요구 사항을 충족합니다.

Public Class OrderItem 
    Public Sub New(ByRef myOrder As Order) 
     myOrder.MyOrderItems.Add(Me) 
    End Sub 
End Class 
  1. 당신은 그것에 유효한 Order 객체를 전달하여 OrderItem을 인스턴스화 할 수 있습니다.
  2. 아직 공개되어 있으며 필요에 따라 호출 할 수 있습니다 (Order.OrderItem(0).ProductID).
  3. OrderItem을 다른 하위 및 함수로 전달할 수 있습니다.
+0

이것은 매우 가깝고 내가 생각해 낸 해결책입니다. 그러나 나는 첫 번째 기준을 정확하게 언급하지 않았으므로 그것을 개정했다. 이 방법의 유일한 문제점은 명령이 인스턴스화를 수행하는 것이 아니라 명령이 어딘가에 존재해야한다는 것입니다. 믹스를해서 미안해. –

+0

@Casey - 공개적으로 액세스가 가능하지만 특정 다른 클래스에서만 인스턴스화 할 수있는 클래스를 원합니다. 지금까지 내가 아는 한, 이것은 .NET (또는 대부분의 다른 OO 언어)에서는 가능하지 않습니다. – Oded

+0

@Stephen Martin 메서드 옆에있는 유일한 방법은 리플렉션을 사용하여 매번 값 비싼 콜이 될 콜 스택을 확인하는 것이고 누구도 추천하지 않을 것이라고 생각합니다. 분명히 런타임에만 실행됩니다. 그러나 나는 그것을 여기에 던질 것이다. New System.Diagnostics.StackTrace(). GetFrame() .GetMethod() .Name <> "CreateAndAddOrder"그런 다음 새 ApplicationException ("잘못된 호출자") 던짐 –

2

OrderItem의 생성자 (만 Order에 accesible) friend해야 - friend를 사용하여 당신이 OrderItem의 가시성을 제한 할 수 있기 때문에이 friend 말을 '동일한 어셈블리의 클래스에 생성자를. 참고 :이 솔루션은 Order 및 OrderItem이 하나의 라이브러리/어셈블리에 있고 다른 어셈블리에서 사용하려고한다는 것을 의미합니다. 그렇지 않으면 friend 보호가 작동하지 않습니다.

Order에 속해야 OrderItem 객체를 생성하는 responsablity : 내부적으로 새로운 OrderItem을 인스턴스화하는 OrderItem 목록에 추가하고 새로 생성에 대한 참조를 반환 Public Function CreateOrderItem(whateverParametersYouNeed) as OrderItem :

Order 클래스와 같은 방법을 구축 목.

그러면 OrderItem으로 원하는대로 할 수 있습니다. 항상 Order의 목록에 속합니다.

+0

모듈이란 무엇입니까? Friend 한정자를 사용하면 어셈블리의 모든 항목을 볼 수있게되었습니다. –

+0

어셈블리는 내가 모듈을 사용하지 말아야한다는 단어입니다. – Ando

관련 문제