可擴展性系統設計的思考
在 面向對象剖析 和 設計模式剖析 兩篇文章中提到面向對象設計是解決複雜系統架構設計有效方法,因為面向對象是模擬人類的思維去發現對象和對象之間的關聯,並且通過面向對象的技術去實現系統的可擴展性。設計模式的核心是面向對象,它把面向對象的三大特性:封閉、繼承、多態,運用得爐火純青,總結出常用的23種設計模式。
找到變化 封裝變化
這是設計模式中,大師提出的一句高度凝練的話,可以說設計模式所做的事情都是圍繞它來講,把它講清楚了,基本上設計模式也就掌握得差不多。有兩個問題隨之出現了:如何找到變化、如何封裝變化呢?
對於"如何找到變化"這個問題,是依靠人主動地思考,這個業務點在未來有沒有可能變化,如果有可能變化,就要想到一個好的設計方式去設計它。
那"如何去封裝變化"呢?找到了這個變化,就要把它"封裝"起來,封裝的意思是對外是透明的,只要按照這個規則做就行,剩下的內容就是討論如何封裝變化。
封裝變化
封裝的手段有多種,但從本質上來講,它的原理就是佔位符思想。告訴這裡是可以變化的,你按照這個規則來做就行了。
變數--最簡單的封裝變化
最簡單的封裝變化的手段就是變數,比如文案、站內信、簡訊、配置,這些都是不能寫死的,後面都有可能是變化的。既然這個變化已經找到,那就封裝它唄,用一個變數來代替,每次程序都讀這個變數,這個變數存儲的地方有很多方法:如資料庫、Memcache、Redis等等。
介面--基礎的封裝變化
提到設計模式,最常用的兩個原則就是"開閉原則"、"面向抽象設計,不依賴於具體的實現",所以一般是先定義一個介面,然後實現類就可以無限擴展,在引用的時候是依賴於介面(抽象)。這是最基礎的封裝變化的手段。
比如策略模式:
interface Strategy{
this.strategy = strategy
} public void doBussice(){ strategy.doBussice(); }}這種模式具有通用性,它的思想是類中引用一個介面,至於介面的實現是什麼我不關心,實現這個介面就可以達到可擴展性。像適配器、代理,雖然它們解決問題不同,但本質做法是一樣的。
這裡有兩個點:一個是對象類型轉換(子類轉換成父類),另一個是多態(面向介面編程)。用這種基本的方法是能解決一部分問題,至少可以做到"開閉原則"、"面向抽象編程",但有時這種模式可引起類爆炸,實現的類太多了,不好控制。
繼承--另一種基礎的封裝變化
除了介面可以實現可擴展性,還有另外一種方法可以實現,那就是繼承,繼承有兩種功能:一個是重用性;另一個是可修改父類特性。正由於繼承子類可以修改父類的特性(是不是可擴展呢?),所以有了到底是用介面還是繼承之爭。有人贊同用介面,不喜歡用繼承,認為繼承有"破壞"的作用在裡面。
比如模板模式:
abstract class template{
}
}public class templateImplA extends template{ public void printHeader(){ 。。。 } public void printBody(){ 。。。 }public void printFooter(){
。。。 }}這樣,可以實現多個子類來達到可擴展性。
介面+繼承--一種高級的封裝變化
上面提到了介面和繼承有過之爭,它們並不是水火不相容的,介面是一種標準,繼承有兩重作用(重用性+可擴展性)。在抽象類中是可以引入介面類,然後在子類中可以重寫這個介面來達到增加功能的特性,裝修模式就是一個典型的例子。
interface Human(){
public void eat(){
。。。 }}abstract class Decorate implements Human{ private Human human; public Decorate(Human human){ this.human = human; } public void eat() {human.eat();
}}public class DecorateImpOne extends Decorate { public DecorateImpOne(Human human) { super(human); } @Override public void eat() { super.eat();addFunction1();
} private void addFunction1(){ System.out.println("go KTV ...."); }}如果你還想增加功能,還可以繼承Decorate去實現更多的子類。
實戰
顧客點餐。
分析:拿到這個需求時,先分析它裡面包含了哪些對象,然後分析這些對象之間的關係是什麼。
對象:顧客、服務員、廚師、命令(菜單)
關聯關係:服務員接收顧客的命令,因此服務員與命令的關聯是包含關係
廚師與命令,廚師是命令的執行者,它們之間是一種包含關係。interface Command{
推薦閱讀: