[C#]代理模式(Proxy)和轉換器模式(Adapter)

[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);
	}
}

結論

其實這兩種模式想要完成的目的都是差不多,只是一個是直接使用類別,一個則是改成用介面的方式而已,如果有任何大大覺得這邊的論點有任何錯誤的話,再請多多指導囉。