組合和繼承,是很基礎的兩種設計模式,甚至在沒有聽說過任何設計模式的時候,就已經用上了這種模式。這兩種模式也被稱爲最基礎的設計模式。但是在真實的使用過程中,一些初學者並不能很好的使用這兩種設計模式,尤其是在兩者混合使用的時候,可能會出現更多的問題。
字面上理解組合和繼承,並沒有太多的差別。但是如何在設計過程中用簡單的理論,創造出經典的設計,又是另外一碼事兒了。下面就根據開源的代碼,看看高手是如何寫代碼的。
代碼來源:httpclient代碼。
整體代碼可以從上面提供的地址下載,文中之引用關鍵代碼,只做說清關係的作用。
我們的程序在運行過程中(尤其是有多個線程的時候),通常需要一個上下文來保存運行過程中的中間值和一些配置參數。在不同的情景下,可能需要不同的上下文體。這個時候,如何設計一種擴展性強的上下文實現,就成了一個問題。
首先,我們需要一個HttpClientContext,如何讓這個類變得上下可擴展,讓我們看看大牛們是怎麼寫代碼的。
public class HttpClientContext extends HttpCoreContext 。其中HttpClientContext是我們在某種情況下需要的一個Context類,爲了向上抽象,構建了一個頂層的核心上下文。
下面是httpCoreContext的定義
public class HttpCoreContext implements HttpContext。HttpContext接口,是上下文在使用過程中需要引用的接口。
簡單的講,這樣實現了多態,只要重寫CoreContext裏面的方法,就可以動態的改變Context的功能。但是這樣明顯顯得靈活性不夠。因爲不同的Context類之間的差別度(差異化的程度)可能不是很大。這樣可能會造成很多的冗餘代碼,並且Context和業務相關,這個在開發及維護方面,顯得有一些缺陷。
上面說的是繼承,單獨的繼承,雖然有可擴展性,但是明顯的顯得不足。
看看下面的代碼
public static HttpCoreContext create() {
return new HttpCoreContext(new BasicHttpContext());
}
public static HttpCoreContext adapt(final HttpContext context) {
Args.notNull(context, "HTTP context");
if (context instanceof HttpCoreContext) {
return (HttpCoreContext) context;
} else {
return new HttpCoreContext(context);
}
}
private final HttpContext context;
public HttpCoreContext(final HttpContext context) {
super();
this.context = context;
}
這是HttpCoreContext的幾種創建方法,這段代碼,起到了相當大的作用
public HttpCoreContext(final HttpContext context) {
super();
this.context = context;
}
運用組合的方式,大大提高了上下文類的擴展性。這樣,如果你想構造一個個性化的上下文,你只需將實現了HttpContext接口的類以參數的形式構造爲HttpCoreContext的任意子類即可。如果所需要的上下文類有個性化的方法,只要在拿到上下文之後,進行向下轉型即可。這樣就大大提高了該上下文的可擴展性。
高手的代碼,總讓人回味無窮。高手也像武俠小說中那樣,將最簡單的招式,化腐朽爲神奇,以別人想不到的方式,作出獨具匠心的設計。