0

内部 ORM ツールの一部を再設計しており、Field (CustomerFirstName などのデータベース内のフィールドを表すクラス) を最終開発者に直接公開したいと考えています。

これは簡単に実現できましたが、この Field クラスは以前は内部で使用されていてオープンすぎたため、API は少し見苦しくなってしまいました。たとえば、これは小さな例の 1 つにすぎません。IsDirty プロパティは読み取り専用ではありませんでした。これは最終開発者が改ざんできないものです。

IPublicField と IPrivateField の 2 つのインターフェイスを作成し、両方を実装するフィールド クラスを取得しようと考えました。ただし、 IsDirty の例を続けると、次のようなものは必要ありません。

Public ReadOnly Property PrivateIsDirty Implements IPrivateField.IsDirty
 ...
End  Property

Public Property IsDirty Implements IPublicField.IsDirty
 ...
End  Property

...少し醜いだけでなく、Field クラスにキャストバックして、非読み取り専用メソッドに入ることができます。また、別のセッター メソッドを導入したくありませんでした。これは、考えたくない別の重大な変更になるためです。また、API の他の部分との不整合も生じるためです。

Field クラスの名前を InnerField に変更し、その周りにファサード/ラッパー スタイルの構造を次のように作成しました。

Public Class Field
    Implements BusinessObjects.IField

    Private InnerField As BusinessObjects.IInnerField

    Public Sub New(ByVal field As IInnerField)
        InnerField = field
    End Sub

    ...

     Public ReadOnly Property IsDirty() As Boolean Implements BusinessObjects.IField.IsDirty
        Get
            Return InnerField.IsDirty
        End Get
    End Property

    ...
End Class

これはかなりうまくいっているようです。内部的には、InnerField は適切にオープンであり、最終開発者に影響を与えることなく、将来さらにオープンにする自由があります。外部的には、Field クラスは、最終開発者が必要とする単純化されたロックダウンされたツールを提供します。

それで、それが首尾一貫していると仮定して、あなたがこの状況でどのように進んだか、そして私の解決策が外部から合理的に見えるかどうか疑問に思っていました.

ありがとう!

4

4 に答える 4

2

VB.NET のコンテキストでは、IsDirty プロパティ スコープのセッターを指定できます。このプロパティをアセンブリ内の他のクラスで「設定可能」にする場合は、スコープを Friend に設定します。

Public Property IsDirty() As Boolean
    Get
        Return _isDirty
    End Get
    Friend Set(ByVal trueFalse As Boolean)
        _isDirty = trueFalse
    End Set
End  Property

これで、外部アセンブリは IsDirty プロパティをチェックできますが、同じアセンブリ内のクラスのみが設定できます。

于 2009-02-04T22:20:49.997 に答える
1

CAS を有利に使用することができます。次に例を示します。

    public bool IsDirty
    {
        get;
        [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, Name = "<assembly name>")]
        set;
    }

属性は System.Security にあります。

開発者がリフレクションを通じて LinkDemand を呼び出すのではないかと心配している場合は、LinkDemand を Demand に変更することをお勧めします: ただし、SecurityAction の代わりにそれらの開発者を「置き換える」こともできます :)。

唯一の問題は、実行時にチェックが行われるようになったことです。これはおそらくあなたが望んでいるものではありませんが、大きな再構築の努力なしに他の方法で機能するとは思えません.

于 2009-02-04T19:13:57.363 に答える
1

プロパティの代わりに get および set メソッドを使用することに反対しない場合は、IPublicField に IPrivateField を実装してみてください。

Public Interface IPrivateField
    Function GetDirty() As Boolean
End Interface

Public Interface IPublicField
    Inherits IPrivateField

    Sub SetDirty(ByVal dirty As Boolean)
End Interface

Public Class Whatever
    Implements IPublicField

    Public Function GetDirty() As Boolean Implements IPrivateField.GetDirty
        ' logic here
    End Function

    Public Sub SetDirty(ByVal dirty As Boolean) Implements IPublicField.SetIsDirty
        ' logic here
    End Sub
End Class

あるいは、VB をやめて C# に切り替えることができれば、これで問題なく動作します。

public interface IPrivateField
{
    bool IsDirty { get;}
}

public interface IPublicField : IPrivateField
{
    new bool IsDirty { get; set; }
}

public class Whatever : IPublicField
{
    public bool IsDirty 
    {
        get
        {
            // logic here
        }
        set
        {
            // logic here
        }
    }
}
于 2009-02-04T19:19:27.977 に答える