2012-05-30 55 views
1

我有一個接口/抽象類,其中的實現可以支持任意大小的字典Nameidentifieridentifier每個實現將具有不同的格式,這是特定於實現的。在C#中接受多種選擇的API設計?

調用者需要從提供者檢索Name的列表,並使用這些來詢問用戶他關心的內容。用戶可以選擇一個或多個。

我考慮了以下設計,其中調用者獲取一個名稱數組,並通過傳入一個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); 

這似乎更清潔,更容易對調用者。

我還有其他選擇嗎?你是如何解決類似的?

+0

@IanMercer我的想法是供應商需要保持反正這個列表,而且我也可以包括在它的選擇。您的建議使用HastSet是一個很好的建議;我會考慮的。謝謝。 – tig

回答

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; 
    } 
} 
0

我喜歡你的第二個例子的一致性。它與使用NameObject類或List <>無關。你可以讓你的第一個例子是一致過:

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

要選擇所有的,你現在可以簡單地寫

SetNamesToUse(GetNames()); 

根據我的經驗,一個用例是不夠的從衆多可能的設計選擇選項。但是,如果你爲更多用例編寫客戶代碼,事情就會開始向你跳出來。

在我上面的單行示例中,GetNames()調用看起來不明確。這是一個調用來獲取用戶名稱或調用來獲取所有可用的名稱嗎?一種方法,更名可以澄清這一點:

SetNamesToUse(GetAllNames()); 

費倫茨·米哈伊 http://theamiableapi.com