Java設(shè)計(jì)模式初探

前言:

最近對(duì)設(shè)計(jì)模式很是著迷,雖然心里念念不忘Rxjava操作符,但是沒(méi)有看過(guò)源碼大州,就想自己實(shí)現(xiàn)起來(lái)還是很難得,況且再下能力還不達(dá)標(biāo)垂谢,所以閑暇時(shí)間就想看下簡(jiǎn)單的厦画,比如設(shè)計(jì)模式,想著以后自己也能多get一項(xiàng)技能滥朱,至少讓代碼看起來(lái)更加美觀那樣咯

關(guān)于java的設(shè)計(jì)模式根暑,我百度到了一些,原本想全部一一講訴徙邻,后來(lái)發(fā)現(xiàn)還是有些難度排嫌,有些設(shè)計(jì)模式從來(lái)沒(méi)見(jiàn)過(guò),應(yīng)該是見(jiàn)識(shí)短淺缰犁,于是就挑了一些比較感興趣的來(lái)介紹

設(shè)計(jì)模式分3種淳地,分別是創(chuàng)建型,結(jié)構(gòu)型民鼓,行為型

1.創(chuàng)建型設(shè)計(jì)模式

1.1 工廠模式:

這個(gè)設(shè)計(jì)模式就是使用一個(gè)靜態(tài)方法返回同一個(gè)接口不同實(shí)現(xiàn)類薇芝,比如定義一個(gè)接口IModule

public interface IModule {
    void action();
}

分別有3個(gè)實(shí)現(xiàn)類

public class ModuleA implements IModule
public class ModuleB implements IModule
public class ModuleC implements IModule

然后使用靜態(tài)方法可以根據(jù)不同類型返回對(duì)應(yīng)實(shí)現(xiàn)類,比如:

public class ModuleFactory {

    public static IModule getModule(int type){
        switch (type) {
            case 0:
                return new ModuleA();
            case 1:
                return new ModuleB();
            default:
                return new ModuleC();
        }
    }
}

1.2 抽象工廠模式:

這個(gè)設(shè)計(jì)模式相當(dāng)于提取1.1里面工程類ModuleFactory的方法作為接口丰嘉,然后創(chuàng)建該接口的指定實(shí)現(xiàn)類夯到,如下:

public interface IFactory {
    IModule getModule();
}

然后創(chuàng)建該接口實(shí)現(xiàn)類工廠:

public class ModuleAFatory implements IFactory {
    @Override
    public IModule getModule() {
        return new ModuleA();
    }
}
public class ModuleBFactory implements IFactory {
    @Override
    public IModule getModule() {
        return new ModuleB();
    }
}
public class ModuleCFactory implements IFactory {
    @Override
    public IModule getModule() {
        return new ModuleC();
    }
}

上面創(chuàng)建ABC的指定生產(chǎn)工廠,然后在需要的時(shí)候使用:

IModule moduleA = new ModuleAFactory().getModule();
IModule moduleB = new ModuleBFactory().getModule();
IModule moduleC = new ModuleCFactory().getModule();

這樣做的好處就是讓指定工廠來(lái)生產(chǎn)特定商品饮亏,但是比1.1多出了接口文件和幾個(gè)實(shí)現(xiàn)的工廠類

1.3 建造者模式

這種設(shè)計(jì)模式就是為了方便構(gòu)建有很多屬性的變量耍贾,在初始化情況下有很多默認(rèn)值可以設(shè)置或者不設(shè)置,而且該對(duì)象不能直接new產(chǎn)生路幸,只能由內(nèi)部類生成荐开,用于保護(hù)對(duì)象
舉個(gè)例子:
定義一個(gè)接口:

public interface IAction {
    void doSomething();
}

使用建造者模式返回一個(gè)實(shí)現(xiàn)對(duì)象:

public class SingleManager implements IAction{
    private String arg1;
    private String arg2;
    private int avg1;
    private int avg2;

    private SingleManager(){}

    void setArg1(String arg1) {
        this.arg1 = arg1;
    }

    void setAvg1(int avg1) {
        this.avg1 = avg1;
    }

    @Override
    public void doSomething() {
    //do other things
    }

    public static class Builder{

        private String arg1 = "default";
        private String arg2 = "default";
        private int avg1 = 1;
        private int avg2 = 2;

        public Builder setArg1(String arg1) {
            this.arg1 = arg1;
            return this;
        }

        public Builder setArg2(String arg2) {
            this.arg2 = arg2;
            return this;
        }

        public Builder setAvg1(int avg1) {
            this.avg1 = avg1;
            return this;
        }

        public Builder setAvg2(int avg2) {
            this.avg2 = avg2;
            return this;
        }

        public IAction build(){
            SingleManager singleManager = new SingleManager();
            singleManager.setArg1(this.arg1);
            singleManager.setAvg1(this.avg1);
            return singleManager;
        }
    }
}

這是一個(gè)簡(jiǎn)單的類,里面有4個(gè)參數(shù)简肴,使用builder內(nèi)部類創(chuàng)建晃听,有默認(rèn)值可以被覆蓋,使用build方法來(lái)產(chǎn)生該對(duì)象,或者返回該對(duì)象實(shí)現(xiàn)的接口能扒,增加接口佣渴,提取方法,這樣做的好處就是可以很好封裝這個(gè)類初斑,讓外部只能初始化一次辛润,并且只能通過(guò)接口訪問(wèn)其方法,很好隱藏里面內(nèi)容的實(shí)現(xiàn)见秤,缺點(diǎn)也有砂竖,就是多了內(nèi)部類,然后代碼也有些重復(fù)

1.4 單例模式

這個(gè)模式我想見(jiàn)過(guò)的人太多了鹃答,只講3種同步的實(shí)現(xiàn)
第一種:靜態(tài)初始化

public class SingleTon {
    public static SingleTon singleTon = new SingleTon();
}

第二種:雙重鎖

public class SingleTon {
    private SingleTon() {
    }

    private static SingleTon instance;
    
    public static SingleTon getInstance(){
        if(instance==null){
            synchronized(SingleTon.class){
                if(instance==null){
                    instance=new SingleTon();
                }
            }
        }
        return instance;
    }
}

第三種:內(nèi)部類

public class SingleTon {
    static class Creator{
        public static SingleTon singleTon = new SingleTon();
    }
    private SingleTon() {
    }

    public static SingleTon getInstance(){
        return Creator.singleTon;
    }
}

1.5 原型模式

該設(shè)計(jì)模式就是將一個(gè)類型復(fù)制乎澄,返回復(fù)制之后的對(duì)象,一般實(shí)現(xiàn)Cloneable接口表示這個(gè)對(duì)象可以被拷貝挣跋,否則調(diào)用clone會(huì)出錯(cuò)

public class MyObject implements Cloneable{

    @Override
    public MyObject clone() throws CloneNotSupportedException {

        return new MyObject();
    }
}

結(jié)構(gòu)性設(shè)計(jì)模式

2.1 適配器模式

使用適配器模式有2種情況三圆,第一種是擴(kuò)展新方法狞换,繼承原類避咆,并且實(shí)現(xiàn)新的接口,這個(gè)方法我感覺(jué)不好修噪,但是能用查库,返回類型會(huì)定死,第二種就是引用原類黄琼,修改之前的接口方法樊销,這個(gè)方法需要修改之前定義的接口,個(gè)人感覺(jué)也不是很好脏款,畢竟需要適配嘛
假設(shè)有一個(gè)接口定義如下:

public interface IAction {
    void execute();
}

實(shí)現(xiàn)類:

public class ModuleAction implements IAction{
    @Override
    public void execute() {
        //do something
    }
}

然后現(xiàn)在由于功能變更围苫,需要加入新的功能。那么就可以這樣:
第一種方式:
添加新的接口

public interface IAction2 {
    void doAction();
}

類繼承擴(kuò)展實(shí)現(xiàn)新接口

public class IAction2Impl extends ModuleAction implements IAction2{

    @Override
    public void doAction() {

    }
}

第二種方式
接口擴(kuò)展:

public interface IActionSub extends IAction{
    void doAction();
}

然后適配原先的類型:

public class IActionAdapter implements IActionSub{
    IAction parent;

    public IActionAdapter(IAction parent) {
        this.parent = parent;
    }

    @Override
    public void execute() {
        this.parent.execute();
    }

    @Override
    public void doAction() {
        //other action
    }
}

這樣IActionAdapter不會(huì)修改之前的類型撤师,也對(duì)其進(jìn)行擴(kuò)展了doAction方法
以上2種方法我個(gè)人偏愛(ài)第二種剂府,不過(guò)具體情況具體分析咯

2.2 裝飾模式
這種模式用于對(duì)一個(gè)類型變量進(jìn)行引用裝飾,并添加額外的操作或者修飾剃盾,主體部分調(diào)用類的相同的方法
舉個(gè)例子:
剛才上面我們看到IActionAdapter 實(shí)現(xiàn)了IActionSub接口腺占,如果我們需要調(diào)用這個(gè)接口需要相同方法并且加入一些其他操作該怎么包裝呢?
下面看這個(gè)包裝類可行不痒谴?

public class IModuleDecr implements IActionSub{
    private IActionSub sub;

    public IModuleDecr(IActionSub sub) {
        this.sub = sub;
    }

    @Override
    public void execute() {
        sub.execute();
        //add process others op
    }

    @Override
    public void doAction() {
        sub.doAction();
        //add process action op
    }
}

這個(gè)方法對(duì)IActionSub的實(shí)現(xiàn)類進(jìn)行引用衰伯,然后也實(shí)現(xiàn)這個(gè)接口,在接口實(shí)現(xiàn)體里面進(jìn)行引用調(diào)用积蔚,然后//add process 用于進(jìn)一步操作或者修飾這個(gè)方法意鲸,這就保證之前的動(dòng)作不被修改,而且也對(duì)之前的操作進(jìn)行了修飾,這就是裝飾模式怎顾,引用原類论矾,實(shí)現(xiàn)相同接口,調(diào)用原類方法并添加額外操作杆勇。

2.3 代理模式
關(guān)于代理模式贪壳,顧名思義,就是外部通過(guò)代理類來(lái)訪問(wèn)蚜退,而代理類實(shí)現(xiàn)細(xì)節(jié)闰靴,具體實(shí)現(xiàn)由目標(biāo)對(duì)象實(shí)現(xiàn),這樣可以增加或者擴(kuò)展目標(biāo)對(duì)象的功能
說(shuō)的有些懵钻注,直接上代碼:

public class IActionProxy implements IActionSub{

    private IActionSub mActionSub;

    public IActionProxy() {
        mActionSub = new IActionAdapter(new ModuleAction());
    }

    @Override
    public void execute() {
        mActionSub.execute();
    }

    @Override
    public void doAction() {
        mActionSub.doAction();
    }
}

承接上面接口蚂且,這是一個(gè)代理類,他對(duì)外的方法只有接口方法幅恋,但是具體實(shí)現(xiàn)卻是由IActionAdapter來(lái)實(shí)現(xiàn)的杏死,我們把IActionAdapter看成目標(biāo)對(duì)象,那么IActionProxy就是代理對(duì)象捆交,這樣就好像外部使用IActionProxy來(lái)調(diào)用接口方法淑翼,但是真正的實(shí)現(xiàn)是目標(biāo)對(duì)象IActionAdapter來(lái)實(shí)現(xiàn)的,這就是代理品追,對(duì)外部不可見(jiàn)玄括,具體實(shí)現(xiàn)由目標(biāo)對(duì)象實(shí)現(xiàn),方便擴(kuò)展于修改

到這里肉瓦,讀者或者有些奇怪遭京,適配器模式,裝飾模式泞莉,代理模式有什么區(qū)別呢哪雕,怎么看上去都是一樣的呢,筆者剛剛學(xué)習(xí)的時(shí)候也會(huì)產(chǎn)生這樣的想法鲫趁,后來(lái)仔細(xì)做了一些比較還是發(fā)現(xiàn)了一點(diǎn)點(diǎn)不同的斯嚎。
——適配器模式:繼承類并實(shí)現(xiàn)新擴(kuò)展接口或者引用類實(shí)現(xiàn)繼承擴(kuò)展的新接口,這個(gè)都是對(duì)原類引用饮寞。
——裝飾模式:也是對(duì)原類引用孝扛,但是卻實(shí)現(xiàn)原類相同接口,并在接口方法調(diào)用引用對(duì)象的方法幽崩,然后再方法內(nèi)部做一些其他操作起到裝飾作用苦始。
——代理模式:這個(gè)模式不會(huì)引用原類,其實(shí)只對(duì)外提供接口方法慌申,但是具體實(shí)現(xiàn)由目標(biāo)對(duì)象陌选,真正的實(shí)現(xiàn)類來(lái)實(shí)現(xiàn)理郑,這就相當(dāng)于封裝之類,外面不知道究竟誰(shuí)實(shí)現(xiàn)了咨油,只管使用您炉。

未完待續(xù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市役电,隨后出現(xiàn)的幾起案子赚爵,更是在濱河造成了極大的恐慌,老刑警劉巖法瑟,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冀膝,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡霎挟,警方通過(guò)查閱死者的電腦和手機(jī)窝剖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)酥夭,“玉大人赐纱,你說(shuō)我怎么就攤上這事“颈保” “怎么了疙描?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蒜埋。 經(jīng)常有香客問(wèn)我淫痰,道長(zhǎng),這世上最難降的妖魔是什么整份? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮籽孙,結(jié)果婚禮上烈评,老公的妹妹穿的比我還像新娘。我一直安慰自己犯建,他們只是感情好讲冠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著适瓦,像睡著了一般竿开。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玻熙,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天否彩,我揣著相機(jī)與錄音,去河邊找鬼嗦随。 笑死列荔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贴浙,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼砂吞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了崎溃?” 一聲冷哼從身側(cè)響起蜻直,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袁串,沒(méi)想到半個(gè)月后袭蝗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡般婆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年到腥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔚袍。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乡范,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啤咽,到底是詐尸還是另有隱情晋辆,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布宇整,位于F島的核電站瓶佳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鳞青。R本人自食惡果不足惜霸饲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臂拓。 院中可真熱鬧厚脉,春花似錦、人聲如沸胶惰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)孵滞。三九已至中捆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坊饶,已是汗流浹背泄伪。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幼东,地道東北人臂容。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓科雳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親脓杉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子糟秘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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

  • 參考資料:菜鳥教程之設(shè)計(jì)模式 設(shè)計(jì)模式概述 設(shè)計(jì)模式(Design pattern)代表了最佳的實(shí)踐,通常被有經(jīng)驗(yàn)...
    Steven1997閱讀 1,174評(píng)論 1 12
  • 設(shè)計(jì)模式匯總 一球散、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用尿赚、多...
    MinoyJet閱讀 3,947評(píng)論 1 15
  • 這是很多年前的事了凌净。那時(shí)他還是一個(gè)見(jiàn)人就會(huì)拘謹(jǐn)?shù)那酀猩瑒倓倧奈鞑窟呥h(yuǎn)的小縣城屋讶,考到繁華的上海讀書冰寻。 那種無(wú)人結(jié)...
    你是我de符合閱讀 236評(píng)論 0 1
  • 從出生到現(xiàn)在為止 我第一次知道了 朋友這種東西不存在全心全意為了對(duì)方而無(wú)視自己的感受的 而且 和有些朋友的關(guān)系 其...
    陸fish閱讀 362評(píng)論 0 0
  • 愛(ài)情總是讓人著迷斩芭,不經(jīng)意間出現(xiàn),卻又在不經(jīng)意間消失乐疆。 或許這句話真的只是一個(gè)人的自我安慰吧划乖。
    秦始皇丶閱讀 337評(píng)論 0 0