[C#]代理模式(Proxy)和轉換器模式(Adapter)
前言
今天想記錄一下Proxy和Adapter這兩種設計模式,為何會放在一起說呢,因為這兩種也是非常相像,其實我們如果不管設計模式的話,也幾乎都是常常使用到的了,接下來模擬情境一下,先從proxy講起吧。
proxy模式
假設今天我有一個所有診所的地址資料,而這資料是從政府公開資料來的,如果不管物件導向的話,應該會直接在ap層就寫了,以web form來說是aspx.cs而mvc的話就是controller,以下則是一個示例
void Main()
{
var client=new HttpClient();
var message=client.GetStringAsync("http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=55ec6d6e-dc5c-4268-a725-d04cc262172b");
var json=JsonConvert.DeserializeObject<MrtResult>(message.Result);
json.Dump();
}
public class MrtResult
{
public Result result { get; set; }
}
public class Result
{
public int offset { get; set; }
public int limit { get; set; }
public int count { get; set; }
public string sort { get; set; }
public Result1[] results { get; set; }
}
public class Result1
{
public string _id { get; set; }
public string Station { get; set; }
public string Destination { get; set; }
public DateTime UpdateTime { get; set; }
}
我們可以試想一下,如果政府的api只要修改了,我們這樣子調用在越多地方出現,就要去四處找出來改,那我們使用proxy模式來包裝一下吧
void Main()
{
var dao=new HttpDao();
var mrtData=dao.GetMrts();
mrtData.Dump();
}
public class HttpDao
{
//抽一個方法出來,以後要修改只要改這邊就好了
public MrtResult GetMrts()
{
var client = new HttpClient();
var message = client.GetStringAsync("http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=55ec6d6e-dc5c-4268-a725-d04cc262172b");
return JsonConvert.DeserializeObject<MrtResult>(message.Result);
}
}
這樣子的話,不管別人提供的api怎麼改,我們只要修改抽出來的方法就可以了
adapter模式
以proxy模式來說,因為我們是使用類別包裝,但是假設今天mrt的資料要改成存進db,那我們就有類似的需求,但有兩種實現的方式,這時候就是適合用adapter的方式了
void Main()
{
IDao httpDao = new HttpDao();
var mrtDataFromHttp = httpDao.GetMrts();
mrtDataFromHttp.Dump();
IDao dbDao = new DbDao();
var mrtDataFromDb = dbDao.GetMrts();
mrtDataFromDb.Dump();
}
public interface IDao //抽出一個介面
{
MrtResult GetMrts();
}
public class DbDao : IDao //一個十Db來的
{
public MrtResult GetMrts()
{
//假設這邊會存回Db的資料
return new MrtResult();
}
}
public class HttpDao : IDao //一個是透過Http來的
{
public MrtResult GetMrts()
{
var client = new HttpClient();
var message = client.GetStringAsync("http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=55ec6d6e-dc5c-4268-a725-d04cc262172b");
return JsonConvert.DeserializeObject<MrtResult>(message.Result);
}
}
結論
其實這兩種模式想要完成的目的都是差不多,只是一個是直接使用類別,一個則是改成用介面的方式而已,如果有任何大大覺得這邊的論點有任何錯誤的話,再請多多指導囉。