ООП - Объекты для сущностей с мастер-списками и композицией объектов - PullRequest
0 голосов
/ 23 февраля 2009

Я пытаюсь понять, как правильно реализовать дизайн ООП для бизнес-объектов, который:

  1. Наличие "основного списка" в базе данных (например, классификации)
  2. Являются частью другого объекта как свойство (т.е. состав объекта), но с дополнительными свойствами

Вот где я застрял в теории. Предположим, у меня есть объект Classification, унаследованный от абстрактного класса BusinessObject с определенными функциями CRUD (MustOverride). Это даст мне:

Public MustInherit Class BusinessObject
    Public Sub New()

    End Sub

    Public MustOverride Function Create() As Boolean
    Public MustOverride Sub Read(ByVal id As Integer)
    Public MustOverride Function Update() As Boolean
    Public MustOverride Function Delete() As Boolean
End Class

Public Class Classification
    Inherits BusinessObject

    <Fields, properties, etc. for ID, Name (or Description), and 
     IsActive. DB table has only these 3 fields.>

    Public Sub New()
        MyBase.New()
    End Sub

    Public Overrides Function Create() As Boolean
        Dal.Classifications.Create(Me)
    End Function

    Public Overrides Function Delete() As Boolean
        Dal.Classifications.Delete(Me)
    End Function

    Public Overloads Overrides Sub Read(ByVal id As Integer)
        Dal.Classifications.Read(Me)
    End Sub

    Public Overrides Function Update() As Boolean
        Dal.Classifications.Update(Me)
    End Function
End Class

Это позволит мне использовать объект классификации в форме, где системный администратор может управлять основным списком классификаций в системе. Здесь нет проблем.

Теперь я хочу, чтобы объект Customer имел свойство типа Classification (состав объекта), но с одним предупреждением - объект Classification требует дополнительного поля Level, когда он становится свойством объекта Customer. Уровень является логической частью классификации в соответствии с бизнесом - классификация имеет числовой уровень, введенный пользователем. Поэтому я создал класс CustomerClassification, унаследованный от Classification:

Public Class CustomerClassification
    Inherits Classification

    Private _level As Integer

    Public Property Level() As Integer
        Get
            Return _level
        End Get
        Set(ByVal value As Integer)
            _level = value
        End Set
    End Property

    Public Sub New()
        MyBase.New()
    End Sub
End Class

И объект Customer будет состоять из CustomerClassification:

Public Class Customer
    Inherits BusinessObject

    Public Property Classification() As CustomerClassification
    ........ etc
End Class

Теперь моя проблема с дизайном заключается в том, что функции Create, Read, Update и Delete все еще доступны в объекте CustomerClassification:

Dim c as New Customer
c.CustomerClassification.Update() ' <-- Not desirable!

Какой другой дизайн я мог бы реализовать здесь? Очевидно, что я делаю это неправильно, но я не вижу простой альтернативной схемы. Я не хочу повторять код в классе CustomerClassification, не наследуя Classification и не повторяя весь код поля и свойства, но я также не хочу выводить функции CRUD на уровень CustomerClassification. Чего мне не хватает в общем дизайне класса?

РЕДАКТИРОВАТЬ: Сохранение уровня классификации в базе данных будет обрабатываться объектом клиента, поскольку база данных является устаревшей, а поле для уровня определено в таблице клиента. 1029 *

Ответы [ 2 ]

1 голос
/ 23 февраля 2009

Если я правильно понимаю вашу проблему, ваш класс Customer не должен агрегировать экземпляр фактического класса Classification. Он должен иметь экземпляр отдельного класса, который определяет уровень и тип классификации, представленной идентификатором или значением перечисления. Класс Classification должен использоваться только в сценарии администратора, поддерживающего список идентификаторов классификации / enum.

0 голосов
/ 23 февраля 2009

Итак, если я правильно понимаю, вы хотите, чтобы функция Update() была доступна только для класса Customer.

Если ваши классы Classification и Customer развернуты в одной сборке, вы можете пометить функцию Update() как friend. Это сделает его недоступным для классов вне этой сборки.

...