你並不真正需要的模式呢。只需以乾淨的方式實施該服務,以便在某個地方使用Image FlikrApi.GetImage(Url)
方法。
// client code
Image image = flickApi.GetImage(url);
當你來實現你的第二個服務,那麼你將對如何根據Url決定調用哪個函數有一些要求。然後,您可以決定如何執行此操作 - 對於兩種服務,它可能與切換頂級域名一樣簡單。所以你有一個開關在一個或另一個對象上調用一個或另一個方法。
readonly FlickrApi flikrApi = new FlickrApi();
readonly WhateverApi whateverApi = new WhateverApi(); // third party
Image GetImage (Url uri) {
switch (url.TopLevelDomain()) {
case "flickr.com":
return flikrApi.GetImage(url);
break;
case "whatever.com":
return whateverApi.GetWhateverImage(url);
break;
default:
throw new UnhandledUriException(uri);
}
// client code
Image image = GetImage(uri);
學會數數 - 一,二,很多。當你點擊很多時,然後考慮重構一個模式。這可能是因爲你正在爲他們開發一個框架,而不是做一些有用的事情,所以你不能實現兩個以上的服務。
如果做有更動態的服務需求,並可選擇僅基於頂級域名,然後我可能有一個地圖 - 填充TLD和服務代表一個Dictionary<string, Func<Url,Image>>
。
readonly Dictionary<string, Func<Url,Image>> apis = new ...;
ImageApi() {
apis["flickr.com"] = new FlickrApi().GetImage;
apis["whatever.com"] = new WhateverApi().GetWhateverImage;
apis["zzze.com"] = (uri) => Zoobers.GetWhateverImage(new ZooberCreds(), uri.ToString());
}
static Image GetImage (Url uri) {
string tld = urli.TopLevelDomain();
if (!imageApis.ContainsKey(tld)) throw new UnhandledUriException(uri);
return imageApis[tld](uri);
}
// client code unchanged
在沒有關閉/代表一種語言,你會定義一個接口,並使用這些,但是C#是比這更好的,並使用內置函數類型,可以使用任何適當的功能,而不是創建一個類只是爲了符合一個接口。這不完全是戰略模式,因爲在上下文和戰略之間沒有結構關係 - 在戰略模式中,有一個上下文有 - 一個戰略,一個戰略而且這個戰略可以改變。我們在這裏根據簡單的條件選擇策略。
如果您在決定使用哪種服務時有更復雜的要求,那麼您最終可能會遍歷接口列表IImageApi
,其中接口包括一個bool HandlesUrl(Url)
方法來詢問服務是否識別Url。在這種情況下,您不必使用代理與任何第三方代碼進行對話,而必須使用包裝。
interface IImageApi {
bool HandlesUri(Url);
Image GetImage(Url);
}
readonly List<IImageApi> apis = new ...;
ImageApi() {
apis.Add(new FlickrApi()); // you wrote this, so it can implement the interface
apis.Add(new WhateverApiAdapter()); // third party requires adapter
apis.Add(new ZoobersApiAdapter()); // ditto
// or you can use something like MEF to populate the list
}
static Image GetImage (Url uri) {
foreach (var api in apis)
if (api.HandlesUri(uri))
return api.GetImage(uri);
throw new UnhandledUriException(uri);
}
// client code unchanged
做最簡單的事情,第二最簡單的事情第二,如果你必須最複雜的事情。
+1同意。希望我有超過1個upvote ... – 2010-06-10 00:42:14