开发者

OOP Design Smell?

Summary

I'm actually writing an object-oriented class library for dealing with the Active Directory in Visual Basic .NET 2005.

The library allows to manage Organizational Units, Groups and Users.

I have strived to generalize as much as I could making my code look like (simplified):

Public Interface IDirectoryEntityBase
    ReadOnly Property DistinguishedName As String
    ReadOnly Property Domain As String
    Property Name As String
    ReadOnly Property Schema As String
End Interface

Public Interface IDirectoryEntity
    Inherits IDirectoryEntryBase

    Property Login As String
End Interface

Public MustInherit Class DirectoryEntity
    Implements IDirectoryEntity

    Private _distinguishedName As String
    Private _domain As String
    Private _name As String
    Private _schema As String

    Public Sub New(ByVal pName As String)
        Name = pName
    End Sub

    Public ReadOnly Property DistinguishedName As String Implements IDirectoryEntryBase.Name
        Get
            Return _name
        End Get
    End Property

    Public ReadOnly Property Domain As String Implements IDirectoryEntryBase.Domain
        Get
            Return _domain
        End Get
    End Property

    Public Property Name As String Implements IDirectoryEntryBase.Name
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            If (String.IsNullOrEmpty(value)) Then Return
            _name = value.Trim()
        End Set
    End Property

    Public ReadOnly Property Schema As String Implements IDirectoryEntryBase.Schema
        Get
            Throw New NotImplementedException()
        End Get
    End Property
End Class

Public Interface IOrganizationalUnit
    Inherits IDirectoryEntity

    ReadOnly Property Children As ICollection(Of IDirectoryEntityBase)
End Interface

Public Class OrganizationalUnit
    Inherits DirectoryEntity
    Implements IOrganizationalUnit

    Private _children As ICollection(Of IDirectoryEntityBase)

    Public Sub New(ByVal pName As String开发者_JS百科)
        MyBase.New(pName)

        _children = new List(Of IDirectoryEntity)()
    End Sub

    Public ReadOnly Property Children As ICollection(Of IDirectoryEntityBase) Implements IOrganizationalUnit.Children
        Get
            Return _children
        End Get
    End Property
End Class

Public Interface IGroup
    Inherits IDirectoryEntity

    ReadOnly Property Members As ICollection(Of IDirectoryEntity)
End Interface

Public Class Group
    Inherits DirectoryEntity
    Implements IGroup

    Private _members As ICollection(Of IDirectoryEntity)

    Public Sub New(ByVal pName As String)
        MyBase.New(pName)

        _members = New List(Of IDirectoryEntity)()
    End Sub

    Public ReadOnly Property Members As ICollection(Of IDirectoryEntity) Implements IGroup.Members
        Get
            Return _members
        End Get
    End Property
End Class

Now, when I have added my instances of whichever type into my Domain.Entries through my Domain.Add Method, I may call the Domain.AcceptChanges Method so that any instances are processed.

My Domain.Entries property is a ICollection(Of DirectoryEntryBase).

Question

It is when I call my Domain.AcceptChanges Method that I find myself handcuffed by having to know what schema or what type I'm working with, since I need to access the OrganizationalUnit.Children or the Group.Members collections depending on their type.

Public Class Domain
    Public Sub AcceptChanges()
        For Each e As DirectoryEntry In Entries
            'How may I find out what collection to work with here?'
        Next
    End Sub
End Class

I have thought about generalizing this collection, but then again, the vocabulary changes from an objet to another. As for an OU, we might speak about Children, when for a Group, we will say Members, etc. In fact, these do not refer to the same reality, so I would generalize this collection for a bad reason, I guess.

Any thoughts?

Thanks!


I think you should genralize the collection as, say, a 'BaseList' which would house the common properties for both OrganizationalUnit.Children and Group.Members.

Then the Children and Member classes could extend that base class and add other custom functionality that needs to occur when you accept changes.

So in summary:

public class BaseList
{
 public virtual void Persist(...);
 // Common stuff
}

public class Children
{
 public override void Persist(...)
 {
   // do custom stuff
 }
}

public class Members
{
 public override void Persist(...)
 {
   // do custom stuff
 }
}

Then you can loop through a collection of 'BaseList' and call each individual persist method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜