1

私は、実装が任意のサイズの辞書をサポートできるインターフェイス/抽象クラスを持っていNameますidentifieridentifier各実装には、実装固有の異なる形式があります。

呼び出し元は、プロバイダーから のリストを取得し、Nameそれらを使用してユーザーに関心のあることを尋ねる必要があります。ユーザーは 1 つ以上を選択できます。

呼び出し元が名前の配列を取得し、int の配列を渡すことでユーザーの選択を設定し、ユーザーが選択した名前の配列インデックスを識別する次の設計を検討しました。

public abstract String[] GetNames();
public abstract void SetNamesToUse(int[] names);

これには満足できず、オブジェクトのリストが渡されるモデルも検討しました。

public class NameObject {
    public bool SelectedByUser;
    public String Name;
    private String ProviderSpecificData;
}

...

public abstract List<NameObject> GetNames();
public abstract void SetNamesToUse(List<NameObject> names);

これは、呼び出し元にとってよりクリーンで簡単に見えます。

他にどのような選択肢がありますか? どのように同様に解決しましたか?

4

2 に答える 2

1

これはどうですか?

interface IIdentifier
{
    string Name {get;}
}

abstract class Identifier<T> : IIdentifier
{
    private readonly string _name;
    private readonly T _id;
    public string Name {get;set;}

    protected Identifier(string name, T id)
    {
        _id = id;
        _name = name;
    }
}

class GuidIdentifier : Identifier<Guid>
{
    public GuidIdentifier(string name, Guid identifier)
        :base(name, identifier)
    {
        //?
    }
}

class UserOptions
{
    private IEnumerable<IIdentifier> _identifiers;

    public IEnumerable<IIdentifier> Identifiers {get {return _identifiers;}}

    public IIdentifier Selected {get;set;}

    public UserOptions(IEnumerable<IIdentifier> identifiers)
    {
        _identifiers = identifiers;
    }
}   
于 2012-05-30T22:10:10.050 に答える
0

2 番目の例の一貫性が気に入っています。NameObject クラスや List<> の使用とは関係ありません。最初の例も一貫させることができます:

public abstract String[] GetNames();
public abstract void SetNamesToUse(String[] names);

すべてを選択するには、次のように書くだけです

SetNamesToUse(GetNames());

私の経験では、多くの可能な設計オプションから選択するには、1 つのユース ケースでは十分ではありません。ただし、より多くのユース ケース用にクライアント コードを記述すると、事態が急変し始めます。

上記の 1 行の例では、GetNames() 呼び出しがあいまいに見えます。ユーザーから名前を取得するための呼び出しですか、それとも使用可能なすべての名前を取得するための呼び出しですか? メソッド名の変更により、これが明確になります。

SetNamesToUse(GetAllNames());

フェレンツ・ミハイ http://theamiableapi.com

于 2012-05-31T16:31:15.223 に答える