成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

Muninn / 1153人閱讀

摘要:適配器模式不應(yīng)在設(shè)計(jì)階段考慮,它是為了解決已經(jīng)上線的問題的存在。組合模式將對(duì)象組合成樹形結(jié)構(gòu)以表示部分整體的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

代理模式

代理模式之前已經(jīng)講過(guò),附上鏈接代理模式

裝飾者模式
裝飾者模式定義:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō),裝飾模式相比生成子類更為靈活。

裝飾模式博主在第一次學(xué)習(xí)是懵逼的,是因?yàn)榇砟J街写韺?duì)象和目標(biāo)對(duì)象都實(shí)現(xiàn)了同一個(gè)接口,裝飾者模式中裝飾對(duì)象和被裝飾對(duì)象也都實(shí)現(xiàn)了同一個(gè)接口,并且都可以很容易的在方法前面或后面增加一些功能來(lái)達(dá)到增強(qiáng)方法的目的。其實(shí)裝飾模式就是代理模式的一個(gè)特殊應(yīng)用,兩者的共同點(diǎn)是都實(shí)現(xiàn)了同一個(gè)接口,不同點(diǎn)就是代理模式著重對(duì)代理過(guò)程的控制,而裝飾模式是對(duì)類的功能進(jìn)行增強(qiáng)或減弱,它著重類的功能變化。
java的規(guī)范必然是jdk源碼了,學(xué)習(xí)裝飾者模式一定要看下io的實(shí)現(xiàn)。io是負(fù)責(zé)讀取數(shù)據(jù)的,而數(shù)據(jù)的來(lái)源又分為文件、字節(jié)數(shù)組、字符緩沖區(qū)、線程輸入流、序列化的對(duì)象等等。如下圖所示:

圖有點(diǎn)丑....輸入流讀取數(shù)據(jù)按照數(shù)據(jù)來(lái)源已經(jīng)分成五類,按理來(lái)說(shuō)應(yīng)該夠用了,那為什么還會(huì)有BufferedInputStream,DataInputStream,PushbackInputStream呢?我們拿bufferinputstream來(lái)分析,因?yàn)閕o流讀取是訪問硬盤,硬盤的訪問速度在計(jì)算機(jī)的世界里一定是極慢的,也是極其耗資源的,為了解決這個(gè)問題,發(fā)明了BufferedInputStream,先讀取buffer,實(shí)在找不到再去硬盤里找。那我們?cè)趺磳⑵浼尤氲絠o家族中呢?如果我們給每種io流增加子類,使其擁有讀取buffer的能力,那么僅以圖中展示出來(lái)的,就要加5個(gè)子類,加上DataInputStream(byte轉(zhuǎn)成java數(shù)據(jù)類型),PushbackInputStream(讀取之后寫回流)那就是15個(gè)子類,已經(jīng)形成了類爆炸的問題,任誰(shuí)看到都是頭大的...
加入我們需要一個(gè)既可以讀buffer又可以將數(shù)據(jù)轉(zhuǎn)成java類型的輸入流,正確的姿勢(shì)是這樣的:

//InputStream inputStream = new BufferedInputStream(new DataInputStream(new FileInputStream("")));
BufferedInputStream inputStream = new BufferedInputStream(new DataInputStream(new FileInputStream("")));

從這里就可以看出來(lái)裝飾者模式和依賴倒置原則是有點(diǎn)沖突的,因?yàn)橐蕾嚨怪迷瓌t讓我們依賴抽象,說(shuō)白了就是面向接口編程,如果我們面向接口使用InputStream聲明,它依然無(wú)法擁有緩存的能力,這證明了想要找出一段完全符合六大設(shè)計(jì)模式的代碼是很難的...

適配器模式
將一個(gè)類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無(wú)法在一起工作的兩個(gè)類能夠一起工作。

適配器模式最好在設(shè)計(jì)階段不要考慮它,他不是為了解決開發(fā)階段存在的問題,而是解決已經(jīng)上線的項(xiàng)目問題。任何一個(gè)架構(gòu)師都不應(yīng)該在設(shè)計(jì)階段考慮使用適配器模式,并且項(xiàng)目一定要嚴(yán)格遵守依賴倒置原則和里氏替換原則,適配器模式才會(huì)帶給你巨大的好處,否則即使在適合用適配器模式的情況下,也會(huì)給項(xiàng)目帶來(lái)巨大改造。
現(xiàn)在假設(shè)這樣一個(gè)場(chǎng)景,A公司收購(gòu)了B公司,要對(duì)B公司的用戶數(shù)據(jù)和項(xiàng)目進(jìn)行一個(gè)內(nèi)部消化,但兩個(gè)系統(tǒng)的實(shí)現(xiàn)又不一樣,如何最小的改動(dòng)最優(yōu)的整合到一起呢?我們拿用戶模塊來(lái)看下,A公司的用戶是這樣設(shè)計(jì)的:

public interface IUserInfo {
    String getName();
    String getSex();
    void getMobile();
}
public class UserInfo implements IUserInfo {

    @Override
    public String getName() {
        System.out.println("老子是光頭強(qiáng)");
    }

    @Override
    public String getSex() {
        System.out.println("老子是男性");
    }
    @Override
    public String getMobile() {
        System.out.println("手機(jī)號(hào):12345678");
    }
}

B公司用戶模塊是這樣設(shè)計(jì)的:

public interface IUserDetail {
    Map getUserBaseinfo();
}
public class UserDetail implements IUserDetail {

    private Map map;

    @Override
    public Map getUserBaseinfo() {
        map = new HashMap();
        map.put("name","張三");
        map.put("sex","男");
        map.put("phone","1896369448");
        return null;
    }
}

首先我們的系統(tǒng)要和他們的系統(tǒng)進(jìn)行交互,不可能為了這一小小的功能對(duì)我們已經(jīng)良好運(yùn)行的項(xiàng)目進(jìn)行大改動(dòng),那怎么辦呢?只能轉(zhuǎn)化了,拿到對(duì)方的數(shù)據(jù)對(duì)象然后轉(zhuǎn)化為我們自己的數(shù)據(jù)對(duì)象。設(shè)計(jì)是這樣子的:

public class NewUser extends UserDetail implements IUserInfo  {
    @Override
    public String getName() {
        String name = (String) super.getUserBaseinfo().get("name");
        System.out.println(name);
        return name;
    }

    @Override
    public String getSex() {
        return (String) super.getUserBaseinfo().get("sex");
    }

    @Override
    public String getMobile() {
        return (String) super.getUserBaseinfo().get("mobile");
    }
}

測(cè)試類是這樣的:

//大boss獲取A公司人員的手機(jī)號(hào),臨時(shí)反悔想要B公司人員的手機(jī)號(hào)
public class Client {

   // public static void main(String[] args) {
        //IUserInfo userInfo = new UserInfo();
        //userInfo.getMobile();  
    //}
    
    public static void main(String[] args) {
       //臨時(shí)改變主意獲取B公司人員的手機(jī)號(hào)
        IUserInfo userInfo1 = new NewUser();
        userInfo1.getMobile();
    }
    
}

使用適配器模式只修改了一句話,其他的業(yè)務(wù)邏輯不用修改就既覺了對(duì)接的問題。適配器可以讓兩個(gè)沒有任何關(guān)系的類在一起運(yùn)行,只要適配器這個(gè)角色能搞定他們就行。適用適配器模式的場(chǎng)景只要記住一點(diǎn)就夠了:當(dāng)你要去修改一個(gè)已經(jīng)投入到生產(chǎn)當(dāng)中的接口,適配器模式可能是最適合你的模式了。適配器模式不應(yīng)在設(shè)計(jì)階段考慮,它是為了解決已經(jīng)上線的問題的存在。

門面模式
要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過(guò)一個(gè)統(tǒng)一的對(duì)象進(jìn)行。門面模式提供一個(gè)高層次的接口,使得子系統(tǒng)更易于使用。

門面模式注重統(tǒng)一的對(duì)象,提供一個(gè)訪問子系統(tǒng)的接口,除了這個(gè)接口不允許有任何訪問子系統(tǒng)的行為發(fā)生。門面對(duì)象是外界訪問子系統(tǒng)內(nèi)部的唯一通道,不管子系統(tǒng)內(nèi)部多么雜亂無(wú)章,只要門面對(duì)象在,就可以做到"金玉其外,敗絮其中"。
源碼中應(yīng)用此模式的非常多,slf4j使用的就是此模式。這是一個(gè)簡(jiǎn)單的設(shè)計(jì)模式,直接給大家上例子:

public interface Drink {
    void drink();
}
public class Milk implements Drink {
    @Override
    public void drink() {
        System.out.println("喝牛奶");
    }
}
public class RedTea implements Drink {
    @Override
    public void drink() {
        System.out.println("喝紅茶");
    }
}
public class Water implements Drink {
    @Override
    public void drink() {
        System.out.println("喝涼白開");
    }
}
public class Facade {

    private Milk milk = new Milk();
    private RedTea redTea = new RedTea();
    private Water water = new Water();

    public void drinkMilk(){
        milk.drink();
    }
    public void drinkRedTea(){
        redTea.drink();
    }
    public void drinkWater(){
        water.drink();
    }
}

統(tǒng)一的對(duì)象指的就是門面,也就是上述例子中的facade。
門面模式可以減少系統(tǒng)間的互相依賴,因?yàn)樗械囊蕾嚩际且蕾囉陂T面對(duì)象,與子系統(tǒng)的業(yè)務(wù)無(wú)關(guān)。只依賴門面對(duì)象,也就是說(shuō)子系統(tǒng)的業(yè)務(wù)如何變化只要不影響到門面對(duì)象,大大提高了靈活性。缺點(diǎn)就是過(guò)于依賴門面對(duì)象,不符合開閉原則,一旦門面對(duì)象中出現(xiàn)錯(cuò)誤,對(duì)子系統(tǒng)的打擊是非常大的,修改門面對(duì)象時(shí),一定要慎之又慎。

組合模式
將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

概念有點(diǎn)抽象,但其實(shí)很簡(jiǎn)單。相信大部分猿都用過(guò),只是不知道他還有這個(gè)名字罷了。簡(jiǎn)單的模式不啰嗦,直接上例子:

public class Person {
    private String name;
    private String age;

    private List list = new ArrayList<>();

    public void addPerson(){
        list.add(new Person());
    }
    public void removePerson(Person person){
        list.remove(person);
    }
    public Person getChild(int i){
        return list.get(i);
    }
}

每個(gè)人都有年齡和姓名,每個(gè)人也都會(huì)有孩子。構(gòu)造成樹形結(jié)構(gòu),使單個(gè)對(duì)象和組合對(duì)象的訪問具有一致性。模式很簡(jiǎn)單,不浪費(fèi)大家時(shí)間。

享元模式
使用共享對(duì)象可有效的支持大量的細(xì)粒度的對(duì)象。

享元模式是池技術(shù)實(shí)現(xiàn)的核心思想。其核心概念有共享對(duì)象和細(xì)粒度的對(duì)象.細(xì)粒度的對(duì)象的特點(diǎn)就是對(duì)象數(shù)量多切性質(zhì)相近,我們應(yīng)將其不變的部分抽出來(lái)形成共享對(duì)象,存放在池中,減少內(nèi)存使用.復(fù)用對(duì)象最簡(jiǎn)單的方式是,用一個(gè) HashMap 來(lái)存放每次新生成的對(duì)象。每次需要一個(gè)對(duì)象的時(shí)候,先到 HashMap 中看看有沒有,如果沒有,再生成新的對(duì)象,然后將這個(gè)對(duì)象放入 HashMap 中.代碼很簡(jiǎn)單,不在舉例.

橋梁模式
將抽象和實(shí)現(xiàn)解耦,使得兩者可以獨(dú)立的變化。

橋梁模式的關(guān)鍵點(diǎn)在于解耦?,F(xiàn)在的公司有很多,我們今天拿互聯(lián)網(wǎng)公司和外包公司來(lái)舉例。每個(gè)公司會(huì)有很多部門,每個(gè)部門工作的方式又不一樣,模式很簡(jiǎn)單,直接上例子:

//抽象部門接口,用來(lái)定義要實(shí)現(xiàn)的方法
public interface IDepartment {
     //每個(gè)部門都要工作,公司請(qǐng)你不是來(lái)吃閑飯的
     void work();
}
//苦逼的程序員
public class Coder implements IDepartment {
    @Override
    public void work() {
        System.out.println("程序猿工作:將咖啡變成代碼");
    }
}
//苦逼的測(cè)試
public class QA implements IDepartment {
    @Override
    public void work() {
        System.out.println("測(cè)試:保證產(chǎn)品質(zhì)量");
    }
}
//it公司
public abstract class ITCompany {
    //引入部門抽象
    private IDepartment iDepartment;

    public ITCompany(IDepartment iDepartment) {
        this.iDepartment = iDepartment;
    }
    public void work(){
        iDepartment.work();
    }
}
//互聯(lián)網(wǎng)公司
class InternetCompany extends ITCompany{

    public InternetCompany(IDepartment iDepartment) {
        super(iDepartment);
    }

}
//外包公司
class outerPackCompany extends ITCompany{

    public outerPackCompany(IDepartment iDepartment) {
        super(iDepartment);
    }
}
public class Client {
    public static void main(String[] args) {
        ITCompany itCompany = new InternetCompany(new Coder());
        itCompany.work();
        ITCompany outerPackCompany = new outerPackCompany(new QA());
        outerPackCompany.work();
    }
}

怎么樣,很簡(jiǎn)單把。它的重點(diǎn)就是解耦,符合開閉原則和依賴倒置原則。在此架構(gòu)的基礎(chǔ)上,我們不管是想要增加抽象還是具體實(shí)現(xiàn)類都是易如反掌。橋梁模式的意圖就是對(duì)變化的封裝,把可能變化的封裝到最小的邏輯單元,避免風(fēng)險(xiǎn)擴(kuò)散.

總結(jié)

設(shè)計(jì)模式到此就算告一段落了。學(xué)習(xí)設(shè)計(jì)模式可以有助于我們寫出優(yōu)雅、易維護(hù)、易擴(kuò)展的代碼,也可以讓我們更好的理解源碼。為了寫設(shè)計(jì)模式的文章,看了兩三本關(guān)于設(shè)計(jì)模式的書,翻閱了許多資料,講的不是特別好,但總歸可以帶大家入門。若是大家想看書學(xué)習(xí),按照難度從低到高可自行選擇:<大話設(shè)計(jì)模式>、<設(shè)計(jì)模式之禪>、gof的<設(shè)計(jì)模式>.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68380.html

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu) - 收藏集 - 掘金

    面試舊敵之紅黑樹(直白介紹深入理解) - Android - 掘金 讀完本文你將了解到: 什么是紅黑樹 黑色高度 紅黑樹的 5 個(gè)特性 紅黑樹的左旋右旋 指定節(jié)點(diǎn) x 的左旋 右圖轉(zhuǎn)成左圖 指定節(jié)點(diǎn) y 的右旋左圖轉(zhuǎn)成右圖 紅黑樹的平衡插入 二叉查找樹的插入 插入后調(diào)整紅黑樹結(jié)構(gòu) 調(diào)整思想 插入染紅后... java 多線程同步以及線程間通信詳解 & 消費(fèi)者生產(chǎn)者模式 & 死鎖 & Thread...

    leeon 評(píng)論0 收藏0
  • 大數(shù)據(jù)導(dǎo)入MySql設(shè)計(jì)空間換時(shí)間的設(shè)計(jì)變更

    摘要:新的數(shù)據(jù)表關(guān)系數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)類似于這樣子大碼中碼小碼這個(gè)表結(jié)構(gòu)的說(shuō)明是避免對(duì)于關(guān)系鏈的數(shù)據(jù)邏輯不理解做的一個(gè)示例。 最近幾天一直在糾結(jié)于一個(gè)大數(shù)據(jù)批量導(dǎo)入的問題,經(jīng)過(guò)幾天思考,發(fā)現(xiàn)基于小數(shù)據(jù)情況,原本的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)是沒有問題的,但是在大量數(shù)據(jù)導(dǎo)入,問題就很大了。我之前一直在強(qiáng)調(diào)程序=數(shù)據(jù)結(jié)構(gòu)+算法,但在這此卻鉆了牛角尖,最后去仔細(xì)看了之前別人設(shè)計(jì)的數(shù)據(jù)表才突然靈光一現(xiàn),發(fā)現(xiàn)了mysql...

    XiNGRZ 評(píng)論0 收藏0
  • 被誤讀的設(shè)計(jì)模式

    摘要:可以說(shuō),如果問題是我們的敵人,代碼是我們的劍,設(shè)計(jì)模式就是高手心中的劍譜。中級(jí)選手,在編程的時(shí)候知道何時(shí)該用什么設(shè)計(jì)模式,而什么時(shí)候不該用。設(shè)計(jì)模式被用來(lái)簡(jiǎn)化設(shè)計(jì),讓設(shè)計(jì)更優(yōu)雅。其中最具有普遍性的方案往往就是我們的設(shè)計(jì)模式的內(nèi)容。 showImg(https://segmentfault.com/img/remote/1460000019100076?w=800&h=440); 目錄概...

    William_Sang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<