我們有時候在應用程序中可能編寫了一些“幽靈”類,“幽靈”類也叫中間類。這些中間類可能什麼事兒都沒做,而只是簡單地調用了其他的組件。這些中間類沒有發揮實際的作用,它們增加了應用程序的層級(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