白話設(shè)計——從類關(guān)系說起

溫故知新,最近更多的是研究和開發(fā)各種類庫,對設(shè)計的是有些感觸.以前在大學(xué)的時候,雖然知道,但是總歸是欠缺經(jīng)驗的,現(xiàn)在,我嘗試用最通俗易懂的方式說出來.

所謂的設(shè)計不正是采用恰當(dāng)?shù)姆绞浇M織雷類關(guān)系么?因此談設(shè)計我認(rèn)為首先要從類之間的關(guān)系開始說起.

在java開發(fā)中,有很多時候我們是在不斷的處理類與類之間關(guān)系,其中這六種關(guān)系是:依賴哼御、關(guān)聯(lián)、聚合恋昼、組合、繼承液肌、實現(xiàn),他們的耦合度依次增強,其在UML的表示如下:


這里寫圖片描述

下面我們分別對這幾種關(guān)系進行說明.

依賴

在實際生活中我們做任何一件事情幾乎都需要借助其他物體的幫助,換句話說矩屁,我們依賴于其他的物體生活爵赵。比如:小明要開車,小明要吃飯空幻,小明要生活等等,不難想象出依賴關(guān)系是現(xiàn)實世界中最普通的關(guān)系秕铛。對于以面向?qū)ο鬄樗枷氲恼Z言世界來說,依賴也是最普遍和常見的關(guān)系但两。

在代碼層次上,依賴關(guān)系多表現(xiàn)為函數(shù)的參數(shù).

public class Person{
    public void drive(Car car){
        //
    }
}

UML表示:


這里寫圖片描述

關(guān)聯(lián)

如果說依賴關(guān)系講求的臨時性谨湘,偶然性的話,那么關(guān)聯(lián)關(guān)系則是一種持久性的關(guān)系紧阔。為什么這么說呢?
小明吃飯借助筷子擅耽,這種關(guān)系只存在小明吃飯的情況下活孩,一旦小明不吃飯了乖仇,那么這種依賴關(guān)系也就終止了。
與依賴關(guān)系不同乃沙,關(guān)聯(lián)對象的雙方地位同級,存在長期崔涂,固定的對應(yīng)關(guān)系,即關(guān)聯(lián)是一種強依賴。關(guān)聯(lián)關(guān)系共分為兩種:單向關(guān)聯(lián)和雙向關(guān)聯(lián)缭保。所謂單向關(guān)聯(lián)通俗點講就是“你中有我,但我中未必有你”艺骂,比如小明擁有一輛車(注意和小明開車進行區(qū)分),但車這個對象可不擁有你啊钳恕。和單向關(guān)聯(lián)相對應(yīng)的是雙向關(guān)聯(lián),也即是"你中有我,我中有你",比如夫妻就是一種雙向關(guān)聯(lián).

在代碼層次上,關(guān)聯(lián)關(guān)系表現(xiàn)為對象作為另一個類的成員變量.

單向關(guān)聯(lián)

public class Person{
    private Car car;
    public void setCar(Car car){
        this.car=car;
    }
}

UML表示:


這里寫圖片描述

雙向關(guān)聯(lián)

public class Husband{
    private Wife wife=new Wife();
    
    public void say(){
        System.out.println("my wife name:"+wife.getName());
    }
    
}

public class Wife{
    private Husband husband=new Husband();
    
    public void say(){
        System.out.println("my husband name:"+husband.getName());
    }
    
}

UML表示:


這里寫圖片描述

聚合

聚合關(guān)系是一種強關(guān)聯(lián)關(guān)系,兩者之間最主呀的區(qū)別是在語意上:聚合之間的關(guān)系更像是"整體-部分",有點組裝的含義,而關(guān)聯(lián)關(guān)系的對象間是相互獨立的,不存在組裝關(guān)系.
在現(xiàn)實世界中,分子是由原子組成的,汽車是由各種零部件組成的等,這都是聚合關(guān)系的最好說明.這里要注意,組成A類型分子的原子也可以組成B類型的分子,這說明什么呢?也就是部分可以單獨存在,換句話說就是整體和部分兩者的生命周期不是同步的.比如:水分子是由氧原子和氫原子組成的,你不能說沒有水分子就沒有氧原子和氫原子吧.

在代碼層次上,聚合和關(guān)聯(lián)兩者的形式一致,都表現(xiàn)為成員變量.

public class Car{
    private Tyre tyre;
    private Engine engine;
    
    public void setTyre(Tyre tyre){
        this.tyre=tyre;
    }
    
    public void setEngine(Engine engine){
        this.engine=engine;
    }
}

UML表示:


這里寫圖片描述

有些人寫成以下樣子:

public class Car{
    private Tyre tyre=new Tyre();
    private Engine engine=new Engine();
    
    
}

咋眼一看在代碼層次上符合啊,那這算不算是聚合關(guān)系呢?首先呢,我們肯定的說這是聚合關(guān)系.但僅僅是形勢上聚合的關(guān)系.為什么這么說呢?

我們從真實世界中抽象汽車這個概念,進而將其轉(zhuǎn)化為軟件世界中的Car,這也是java中提倡的面向?qū)ο缶幊痰?但是呢,在從真實世界到軟件世界的這個過程中需要保證物體靜態(tài)屬性和動態(tài)屬性沒變.什么意思呢,換言之就是,你將真實世界中的汽車轉(zhuǎn)成換成軟件世界中Car,反過來,也要保證從軟件世界中Car能夠轉(zhuǎn)換成真實世界中的汽車.如果不能保證轉(zhuǎn)換的一致性,那么就說明,抽象過程中出現(xiàn)了問題.

現(xiàn)在將上邊的代碼中的Car轉(zhuǎn)成現(xiàn)實世界中的汽車,我們發(fā)現(xiàn)轉(zhuǎn)換后的汽車竟然不能換車輪了?這可能嗎?很顯然,在對抽象汽車到Car這個類的過程中出現(xiàn)了問題.那么應(yīng)該怎么樣的呢?
除了一開始我們寫的那樣,還可以如下:

public class Car{
    private Tyre tyre=new Tyre();
    private Engine engine=new Engine();
    
    public void setTyre(Tyre tyre){
        this.tyre=tyre;
    }
    
    public void setEngine(Engine engine){
        this.engine=engine;
    }
}


組合

組合和聚合非常類似,都表示的"整體-部分",但是組合要求整體和部分的生命周期是同步的,部分不能脫離整體而存在.不難發(fā)現(xiàn),組合是一種強聚合關(guān)系.比如,人這個生命體由不同器官構(gòu)成,其中我們拿心臟來說一下,人要活著必須依靠心臟,心臟不能脫離人這個生命體,兩者一旦分開,都會死亡.
在代碼層次上,通常表現(xiàn)為類的成員變量,除此之外還要求這個成員變量在構(gòu)造函數(shù)中創(chuàng)建.

public class People{
    private Heart heart;
    
    public People(){
        heart=new Heart();
    }
}

UML表示:


這里寫圖片描述

到現(xiàn)在我們從微觀的角度了解依賴,關(guān)聯(lián),聚合和組合這四種關(guān)系,從宏觀上來說,這四種關(guān)系體現(xiàn)的都是對象與對象之間的依賴,因此在某些方面,我們也同依賴來涵蓋這四種關(guān)系.在很多文章中,并沒有說到這一點,這也造成,很多情況下,大家對這幾個概念探地的時候感到很疑惑.

從真實世界中來看,對象與對象之間的關(guān)系其實可以分為兩類,一是上邊宏觀所說的依賴,另一種則是我們下面要談的泛化


泛化

在開始解釋泛化之前,先來從extends說起:

extends的意思是延伸,擴展,繼承.從這個詞的角度來說,子類應(yīng)該分為兩層意思:

一種是增強原有類的功能,這體現(xiàn)的不是生物界的"父與子"關(guān)系.比如我現(xiàn)在擁有一個工具類Tools,現(xiàn)在我想要增強該工具類,按照開閉原則,我定義了UpdateTools extends Tools,此時你就不能說UpdateTools是Tools的"孩子",因為你發(fā)現(xiàn)這里的UpdateTools僅僅是增強原有Tools類的功能,作為功能擴展類來的.此時,我們稱其為擴展比較合適.

另一種則就是體現(xiàn)生物界的"父與子",即子類和父類在某些行為或者屬性的表現(xiàn)不一樣.這時候,用單詞inherit來表示更合適,也就是我們常說的繼承的意思.

到現(xiàn)在,相信你已經(jīng)明白了extends的含義.其實,實際中,我們使用繼承的目的就是為了擴展,因此,可不做深究.
之所以談到這一點,是因為去年帶過的一個實習(xí)生僅僅因為不理解extends中的兩層,而覺得通過UpdateTools擴展Tools是有問題的.

下面我們在來說泛化.
泛化表示一個類(父類或接口)與其一個或者多個變體之間的關(guān)系.簡單的來說泛化表示類與類之間的擴展,接口與接口的擴展,類與接口之間的實現(xiàn)關(guān)系.
在java中用extends來表示擴展,用implements表示實現(xiàn)關(guān)系.

擴展:

public class Tools{
    public void print(){
        //do 
    }
}

public class UpdateTools extens Tools{
    public void printError(){
        //do
    |
    
}

繼承:

public class Father{
    public void getName(){
        //do
    }
}

public class Son{
    public void other(){
        //do
    }
}

UML表示:


這里寫圖片描述

實現(xiàn):

public interface UserService{
    void execute();
}

public class UserServiceImpl implements UserService{

    @override
    void execute(){
        //do
    }
}


UML表示:


這里寫圖片描述

到現(xiàn)在厘肮,相信你對類關(guān)系有了清晰的理解了睦番。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市托嚣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌示启,老刑警劉巖兢哭,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夫嗓,死亡現(xiàn)場離奇詭異,居然都是意外死亡啤月,警方通過查閱死者的電腦和手機煮仇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門谎仲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人郑诺,你說我怎么就攤上這事≌薜” “怎么了辙售?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵飞涂,是天一觀的道長祈搜。 經(jīng)常有香客問我,道長士八,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任婚度,我火速辦了婚禮,結(jié)果婚禮上蝗茁,老公的妹妹穿的比我還像新娘。我一直安慰自己哮翘,他們只是感情好颈嚼,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布忍坷。 她就那樣靜靜地躺著熔脂,像睡著了一般佩研。 火紅的嫁衣襯著肌膚如雪霞揉。 梳的紋絲不亂的頭發(fā)上旬薯,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天适秩,我揣著相機與錄音绊序,去河邊找鬼秽荞。 笑死骤公,一個胖子當(dāng)著我的面吹牛扬跋,可吹牛的內(nèi)容都是我干的阶捆。 我是一名探鬼主播钦听,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朴上!你這毒婦竟也來了垒棋?” 一聲冷哼從身側(cè)響起痪宰,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤畔裕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后乖订,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡垢粮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜡吧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡昔善,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出君仆,到底是詐尸還是另有隱情,我是刑警寧澤返咱,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布钥庇,位于F島的核電站,受9級特大地震影響咖摹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜萤晴,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望店读。 院中可真熱鬧嗦枢,春花似錦屯断、人聲如沸文虏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剃氧。三九已至敏储,卻和暖如春朋鞍,著一層夾襖步出監(jiān)牢的瞬間已添,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工更舞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缆蝉。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像刊头,于是被迫代替她去往敵國和親黍瞧。 傳聞我的和親對象是個殘疾皇子原杂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容