看侯捷老師的課程講羡榴,面對(duì)對(duì)象的類的組織關(guān)系有三種匀归,組合坑资,委托,和繼承穆端。
組合:一個(gè)類“有一個(gè)”另一個(gè)類型的實(shí)例作為成員盐茎,如
class A {
B b;
}
委托:一個(gè)類有另一個(gè)類的實(shí)例的指針類型作為成員,如
class A {
B *b
}
繼承:一個(gè)類徙赢,是另一個(gè)類的一種派生, 如
class A:public B{}
作為一個(gè)java程序員字柠,組合和繼承是常常用的,只是對(duì)委托這種東西不是很理解狡赐。
這篇文章結(jié)合java對(duì)委托做一個(gè)解析
委托模式下類成員就是java里說(shuō)的接口
在java web中的業(yè)務(wù)一般都會(huì)分為:表現(xiàn)層窑业,業(yè)務(wù)邏輯層,數(shù)據(jù)訪問(wèn)層枕屉。
其中業(yè)務(wù)邏輯層處理業(yè)務(wù)邏輯常柄,有必要時(shí)調(diào)用數(shù)據(jù)訪問(wèn)層操作數(shù)據(jù)庫(kù)的數(shù)據(jù)。
比如一個(gè)商城系統(tǒng)要獲取一條訂單信息有關(guān)的業(yè)務(wù)邏輯層的類可能是下面這樣
// 業(yè)務(wù)邏輯層處理訂單信息的類
class OrderServiceImp {
// 數(shù)據(jù)訪問(wèn)層委托對(duì)象
OrderDao orderDao;
Order getById(int id) { return orderDao.getById(id); }
}
這個(gè)orderDao在java里是個(gè)接口搀擂,在c++里實(shí)際就是存放的基類指針西潘。這就引出下面的話題。
委托的目的:解耦
上面說(shuō)的orderDao它的代碼都是抽象的哨颂,用c++表示就是它的成員函數(shù)都是virtual xxx = 0;
這樣做有什么好處呢喷市,小標(biāo)題里也說(shuō)了,解耦威恼。
OrderDao只對(duì)外提供增刪改查方法的接口品姓,不必展示內(nèi)部的細(xì)節(jié),OrderService將一些操作“委托”給OrderDao箫措,也不必糾結(jié)于OrderDao的實(shí)現(xiàn)細(xì)節(jié)腹备。
使用時(shí),只需讓orderDao“指針”指向自己寫的派生類斤蔓,假如今天我用mysql作為數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù)植酥,明天用oracle,只需使用時(shí)讓OrderService的成員指針指向繼承了OrderDao的派生類弦牡,同樣的代碼就展現(xiàn)出了不同的效果(c++有個(gè)規(guī)定友驮,派生類向基類的自動(dòng)類型轉(zhuǎn)換只對(duì)指針或引用類型有效。)
沒(méi)代碼說(shuō)個(gè)XX
今天狀態(tài)不太好喇伯,總感覺(jué)表達(dá)不出來(lái)我真正想說(shuō)的喊儡,還是上一段代碼吧拨与,模擬一段情景稻据。
假如我要做一個(gè)游戲,一開(kāi)始沒(méi)有美工,只好用ascii字符表示人物捻悯,場(chǎng)景匆赃,物品。有個(gè)控制ui的類
class UI {
virtual void draw();
}
我的地圖類成員包含一個(gè)UI類的指針今缚,當(dāng)生成地圖時(shí)調(diào)用draw函數(shù)繪制地圖
class Map {
public:
void draw() { ui->draw(); }
void setup(UI *u) { ui = u; }
private:
UI *ui;
}
使用ascii字符的界面
class AsciiUI:public UI {
void draw() override {
// 打印界面
}
}
在游戲主程序里算柳,我要生成地圖
int main() {
Map p;
AsciiUI a;
p.setup(a);
p.draw();
}
這樣,一個(gè)ascii界面地圖就生成了姓言。
現(xiàn)在投資商來(lái)投了一個(gè)億瞬项,我請(qǐng)了個(gè)美工,畫出超牛的3d地圖何荚。那我現(xiàn)在要將畫出地圖囱淋,人物,菜單餐塘,物品等等界面都改為畫3d的妥衣,我要改寫所有類的代碼嗎?還好不用戒傻,我只需要修改UI的派生類Ascii税手,或者重新寫一個(gè)派生類,這樣的話需纳,甚至游戲程序的其他部分都不知道界面有改變芦倒,業(yè)務(wù)邏輯等等都可以直接使用。
class 3dUI:public UI {
void draw() override { ... }
}
這樣將自己的任務(wù)可以分離出來(lái)的地方不翩,委派給別人的思想熙暴,實(shí)際上就是面對(duì)對(duì)象設(shè)計(jì)的核心要素高內(nèi)聚,低耦合的體現(xiàn)
在設(shè)計(jì)類時(shí)只要把握住這個(gè)核心要素慌盯,其他都是實(shí)現(xiàn)它的小技巧而已周霉。