2016-04-14 14 views
4

當我開發時,我通常會嘗試遵循SOLID原則。 通常您有一個接口,所有受影響的類都會實現,然後在進行進一步計算時將該接口用作參數。從Web服務獲取數據時的清潔代碼:SRP和打開/關閉

我的問題是,如何在調用Web服務時實現這一目標?下面的代碼不是非常精簡,並且確實不符合單一責任模式和開放/關閉原則。

你將如何重新設計瞭如下的代碼遵循SRP和O/C:

public class Fetch 
    { 
     public void Run() 
     { 
      var url = "https://api.nasa.gov/planetary/apod?api_key=NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo"; 
      var client = new HttpClient(); 
      var response = client.GetAsync(url).Result; 
      var data = response.Content.ReadAsStringAsync().Result; 
      var parsedData = JsonConvert.DeserializeObject<Nasa>(data); 

      if(parsedData.media_type.Equals("image")) 
      { 
       CreateImage(parsedData); 
      } 

      if (parsedData.media_type.Equals("video")) 
      { 
       CreateVideo(parsedData); 
      } 

      if (parsedData.media_type.Equals("text")) 
      { 
       CreateText(parsedData); 
      } 
     } 
    } 

    public class Nasa 
    { 
     public string copyright { get; set; } 
     public string date { get; set; } 
     public string explanation { get; set; } 
     public string hdurl { get; set; } 
     public string media_type { get; set; } 
     public string service_version { get; set; } 
     public string title { get; set; } 
     public string url { get; set; } 
    } 

(API密鑰是由美國宇航局的示例站點採取所以不用擔心暴露它的異步部分使用.Result就是這個例子)

+2

這會更好codereview –

+0

這不是我們正在使用的代碼。這只是關於Clean Code和Web Services的一般性問題/討論。 – Hypnobrew

+2

這仍然是一個codereview(程序員推)問題 - 你已經發布了正在運行的代碼,並且正在詢問如何從標準的角度來改進它。無論你是否真的使用代碼並不重要。 –

回答

3

不知道太多你的需求,或如何CreateVideo(item)CreateImage(item)工作,你可以用這個作爲一個起點。

請注意,如果您正在使用依賴容器(如Simple Injector,喜歡它!),容器可以提供以下大部分依賴項。

public class Nasa 
{ 
    public string copyright { get; set; } 
    public string date { get; set; } 
    public string explanation { get; set; } 
    public string hdurl { get; set; } 
    public string media_type { get; set; } 
    public string service_version { get; set; } 
    public string title { get; set; } 
    public string url { get; set; } 
} 

public interface ITransformFetch<in T> 
{ 
    void Transform(T data); 
} 

public interface IFetch<T> 
{ 
    T Fetch(); 
} 

public class NasaFetcher : IFetch<Nasa> 
{ 
    private const string NasaUrl = "https://api.nasa.gov/planetary/apod?api_key=NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo"; 

    private readonly IHttpClientWrapper _client; 

    public NasaFetcher(IHttpClientWrapper client) 
    { 
     _clientFactory = client; 
    } 

    public Nasa Fetch() 
    { 
     var response = _client.GetAsync(NasaUrl).Result; 
     var data = response.Content.ReadAsStringAsync().Result; 
     return JsonConvert.DeserializeObject<Nasa>(data); 
    } 
} 

public class NasaFetchImageTransformer : ITransformFetch<Nasa> 
{ 
    public void Transform(Nasa data) 
    { 
     // transform data 
    } 
} 

public class NasaFetchVideoTransformer : ITransformFetch<Nasa> 
{ 
    public void Transform(Nasa data) 
    { 
     // transform data 
    } 
} 

public class NasaFetcherTransformerDecorator : IFetch<Nasa> 
{ 
    private readonly IFetch<Nasa> _fetcher; 

    public NasaFetcherTransformerDecorator(IFetch<Nasa> fetcher) 
    { 
     _fetcher = fetcher; 
    } 

    public Nasa Fetch() 
    { 
     var result = _fetcher.Fetch(); 
     if (result != null) 
     { 
      switch (result.media_type) 
      { 
       case "image": 
        var nasaFetchImageTransformer = new NasaFetchImageTransformer(); 
        nasaFetchImageTransformer.Transform(result); 
        break; 

       case "video": 
        var nasaFetchVideoTransformer = new NasaFetchVideoTransformer(); 
        nasaFetchVideoTransformer.Transform(result); 
        break; 
      } 
     } 

     return result; 
    } 
} 

public class Test 
{ 
    public void TestNasaFetcher() 
    { 
     var data = new NasaFetcherTransformerDecorator(new NasaFetcher(new HttpClientWrapper())); 
     var nasa = data.Fetch(); 
    } 
} 
+0

嗯,所以如果API添加了一個新的媒體類型,我們添加一個新的Transformen,然後添加一個新的案例'在交換機中。這不是打破了「開放/關閉原則」嗎? – Hypnobrew

+0

您也可以繼續爲每個變壓器製作裝飾器幷包裝對象 - 很可能使用IoC容器。 – janhartmann