我們有時候在應用程序中可能編寫了一些“幽靈”類,“幽靈”類也叫中間類。這些中間類可能什麼事兒都沒做,而只是簡單地調用了其他的組件。這些中間類沒有發揮實際的作用,它們增加了應用程序的層級(layer),並且增加了應用程序的復雜性。這時,我們應將這樣的中間類刪除,甚至刪除中間類所處的“中間層”——這就是本文要講的重構策略“移除中間類”。
這個重構策略比較容易理解,下面這幅圖演示了它的重構過程。
通常情況下,無效的中間類可能是因為濫用設計模式而造成的。
如果設計模式使用的恰當,這個重構策略就不適用了,比如用“門面模式”、“適配器模式”和“代理模式”的場景。
下面我以“門面模式”簡單說明一下不適用的場景。
門面模式,是指提供一個統一的接口去訪問多個子系統的多個不同的接口,它為子系統中的一組接口提供一個統一的高層接口。使得子系統更容易使用。
通過區分“門面模式”的使用場景,可以判斷是否應該使用“移除中間類”:
1、客戶只需要使用某個復雜系統的子集,或者需要以一種特殊的方式與系統交互時,使用門面模式。
2、當需要跟蹤原系統的使用情況時 ,使用門面模面模式。因為所有對系統的訪問都經過FACADE,所以可以很容易地監視系統的使用 。
3、 希望封裝和隱藏原系統時。
4、編寫新類的成本小於所有人使用和維護原系統使用所需的成本時
這段代碼定義了3個類,Consumer依賴於AccountManager,AccountManager依賴於AccountDataProvider。
隱藏代碼public class Consumer
{
public AccountManager AccountManager { get; set; }
public Consumer(AccountManager accountManager)
{
AccountManager = accountManager;
}
public void Get(int id)
{
Account account = AccountManager.GetAccount(id);
}
}
public class AccountManager
{
public AccountDataProvider DataProvider { get; set; }
public AccountManager(AccountDataProvider dataProvider)
{
DataProvider = dataProvider;
}
public Account GetAccount(int id)
{
return DataProvider.GetAccount(id);
}
}
public class AccountDataProvider
{
public Account GetAccount(int id)
{
// get account
}
}
AccountManager類作為中間類,沒有起到任何實際的作用,它只是依葫蘆畫瓢地套用了AccountDataProvider做的事情。
移除中間類後,Consumer類直接依賴於AccountDataProvider類。
隱藏代碼public class Consumer
{
public AccountDataProvider AccountDataProvider { get; set; }
public Consumer(AccountDataProvider dataProvider)
{
AccountDataProvider = dataProvider;
}
public void Get(int id)
{
Account account = AccountDataProvider.GetAccount(id);
}
}
public class AccountDataProvider
{
public Account GetAccount(int id)
{
// get account
}
}
【關注】keepfool