C#定義一個Call API並返回Stream的共用方法_參數支援傳入不同物件的彈性設計(依賴倒轉原則DIP)
在很久以前有寫過有關SOLID的文章
設計模式特訓_Day01_SOLID五項鐵則
如今在專案偕同過程也遇到實踐機會
假設我今天有一個method想要傳入固定要做
json反序列化成其對應物件的Model Class
這種Model Class可能在專案裡面有一或多個
IC_KeyWord_Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; /// <summary> /// IC_KeyWord_Model 的摘要描述 /// </summary> public class IC_KeyWord_Model { [JsonProperty(PropertyName = "keyword")] public string keyword { get; set; } [JsonProperty(PropertyName = "similar words")] public string[] similarwords { get; set; } [JsonProperty(PropertyName = "additional words")] public string[] additionalwords { get; set; } } |
IC_RcmdAssg_Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; /// <summary> /// IC_AssigneeList_Model 的摘要描述 /// </summary> public class IC_RcmdAssg_Model { public Assignee_List[] assignee_list { get; set; } public int rtnc { get; set; } } public class Assignee_List { public string oriAssgName { get; set; } public string oriAssgCountry { get; set; } public string rcmdName { get; set; } public string rcmdCountry { get; set; } } |
這時你會去針對不同物件傳入型態都寫作同樣方法的物件嗎
然後專案裡面這支Class都是一堆重複做同樣事情的method
差別只在於傳入的參數物件型態?
這時就要用到 SOLID當中的Dependency Inversion Principle(DIP)
高層模組不該依賴低層模組(Class....)。
-->換言之,外部在調用的區塊(可能是你的main或多個程式檔案、其他的方法、函數當中)
不該頻繁修改。
兩者(高低層模組)皆應該依賴其抽象,抽象不該依賴細節,細節應該依賴抽象。
在白話一點說,就是實例化的Class之間不發生依賴關係,其依賴關係
透過Interface或Abstract來產生。
一個生活實例:
假設今天某一間公司開的職缺要找一個日文翻譯的人
不可能說限定台大日文或輔仁日文、東吳日文、.....
因為這樣會導致不好招到人且資格範圍太限縮
而是找一個通過某個具有公信力日文檢定、認證。
Interface 就有點類似通過某個認證具有某個資格的涵義
而具體每個人各自是怎麼通過該項認證的都有下不同的苦功。
,公司應徵職務的人不在乎只看你有無拿到該認證資格而已
定義IApiModel介面
1 2 3 4 5 6 7 8 9 10 11 12 | using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// IApiModel 的摘要描述 /// </summary> public interface IApiModel { object DeserializObj(System.IO.StreamReader sr); } |
公用方法中定義要進去的參數寫的是一種資格
只要有實作IApiModel介面的物件都有資格傳入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Net; using System.Text; using System.IO; using Newtonsoft.Json; /// <summary> /// HttpHelper 的摘要描述 /// </summary> public class HttpHelper { public HttpHelper() { // // TODO: 在這裡新增建構函式邏輯 // } public static object SendHttpRequest(string requestURI, string requestMethod, string json, string Authorization, IApiModel apiModel) //Dependency Inversion Principle(DIP) , 只要是有implement IApiModel中定義的DeserializObj方法的Model Class都可傳入。 { HttpWebRequest request; HttpWebResponse response; request = (HttpWebRequest)WebRequest.Create(requestURI); request.Timeout = 15000; request.Method = requestMethod; request.ContentType = "application/json"; request.Headers.Add("charset", "utf-8"); request.Headers.Add("Authorization", Authorization); request.KeepAlive = false; byte[] requestBody = Encoding.UTF8.GetBytes(json); request.ContentLength = requestBody.Length; Stream requestStream = request.GetRequestStream(); requestStream.Write(requestBody, 0, requestBody.Length); response = (HttpWebResponse)request.GetResponse(); object objResponse = null; if (response.StatusCode != HttpStatusCode.OK) { string tt = response.StatusCode.ToString(); } if (response.GetResponseStream() != null) { StreamReader myStreamReader = new StreamReader(response.GetResponseStream() ?? Stream.Null, Encoding.UTF8); objResponse = apiModel.DeserializObj(myStreamReader); myStreamReader.Close(); } return objResponse; } } |
實作IApiModel介面的IC_KeyWord_Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; /// <summary> /// IC_KeyWord_Model 的摘要描述 /// </summary> public class IC_KeyWord_Model : IApiModel { [JsonProperty(PropertyName = "keyword")] public string keyword { get; set; } [JsonProperty(PropertyName = "similar words")] public string[] similarwords { get; set; } [JsonProperty(PropertyName = "additional words")] public string[] additionalwords { get; set; } public object DeserializObj(StreamReader sr) { JsonSerializer jsonSerializer = new JsonSerializer(); return (IC_KeyWord_Model)jsonSerializer.Deserialize(sr, typeof(IC_KeyWord_Model)); } } |
實作IApiModel介面的IC_RcmdAssg_Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; /// <summary> /// IC_AssigneeList_Model 的摘要描述 /// </summary> public class IC_RcmdAssg_Model : IApiModel { public Assignee_List[] assignee_list { get; set; } public int rtnc { get; set; } public object DeserializObj(StreamReader sr) { JsonSerializer jsonSerializer = new JsonSerializer(); return (IC_RcmdAssg_Model)jsonSerializer.Deserialize(sr, typeof(IC_RcmdAssg_Model)); } } public class Assignee_List { public string oriAssgName { get; set; } public string oriAssgCountry { get; set; } public string rcmdName { get; set; } public string rcmdCountry { get; set; } } |
留言
張貼留言