小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

設(shè)計(jì)模式(十六)——訪(fǎng)問(wèn)者模式

 路人甲Java 2021-05-05

1 測(cè)評(píng)系統(tǒng)的需求

完成測(cè)評(píng)系統(tǒng)需求

1) 將觀(guān)眾分為男人和女人,對(duì)歌手進(jìn)行測(cè)評(píng),當(dāng)看完某個(gè)歌手表演后,得到他們對(duì)該歌手不同的評(píng)價(jià)(評(píng)價(jià) 有不同的種類(lèi),比如 成功、失敗 )

 

 

2) 傳統(tǒng)方案

2 傳統(tǒng)方式的問(wèn)題分析

1) 如果系統(tǒng)比較小,還是 ok 的,但是考慮系統(tǒng)增加越來(lái)越多新的功能時(shí),對(duì)代碼改動(dòng)較大,違反了 ocp 原則, 不利于維護(hù)

2) 擴(kuò)展性不好,比如 增加了 新的人員類(lèi)型,或者管理方法,都不好做

3) 引出我們會(huì)使用新的設(shè)計(jì)模式 – 訪(fǎng)問(wèn)者模式

3 訪(fǎng)問(wèn)者模式基本介紹

1) 訪(fǎng)問(wèn)者模式(Visitor Pattern),封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)的各元素的操作,它可以在不改變數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。

2) 主要將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離,解決 數(shù)據(jù)結(jié)構(gòu)和操作耦合性問(wèn)題

3) 訪(fǎng)問(wèn)者模式的基本工作原理是:在被訪(fǎng)問(wèn)的類(lèi)里面加一個(gè)對(duì)外提供接待訪(fǎng)問(wèn)者的接口

4) 訪(fǎng)問(wèn)者模式主要應(yīng)用場(chǎng)景是:需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同操作(這些操作彼此沒(méi)有關(guān)聯(lián)),同時(shí)

需要避免讓這些操作"污染"這些對(duì)象的類(lèi),可以選用訪(fǎng)問(wèn)者模式解決

4 訪(fǎng)問(wèn)者模式的原理類(lèi)圖

 

  • 對(duì)原理類(lèi)圖的說(shuō)明-

即(訪(fǎng)問(wèn)者模式的角色及職責(zé))

1) Visitor 是抽象訪(fǎng)問(wèn)者,為該對(duì)象結(jié)構(gòu)中的 ConcreteElement 的每一個(gè)類(lèi)聲明一個(gè) visit 操作

2) ConcreteVisitor :是一個(gè)具體的訪(fǎng)問(wèn)值 實(shí)現(xiàn)每個(gè)有 Visitor 聲明的操作,是每個(gè)操作實(shí)現(xiàn)的部分.

3) ObjectStructure 能枚舉它的元素, 可以提供一個(gè)高層的接口,用來(lái)允許訪(fǎng)問(wèn)者訪(fǎng)問(wèn)元素

4) Element 定義一個(gè) accept  方法,接收一個(gè)訪(fǎng)問(wèn)者對(duì)象

5) ConcreteElement 為具體元素,實(shí)現(xiàn)了 accept  方法

5 訪(fǎng)問(wèn)者模式應(yīng)用實(shí)例

應(yīng)用實(shí)例要求

1) 將人分為男人和女人,對(duì)歌手進(jìn)行測(cè)評(píng),當(dāng)看完某個(gè)歌手表演后,得到他們對(duì)該歌手不同的評(píng)價(jià)(評(píng)價(jià) 有不同的種類(lèi),比如 成功、失敗 ),請(qǐng)使用訪(fǎng)問(wèn)者模式來(lái)說(shuō)實(shí)現(xiàn)

2) 思路分析和圖解(類(lèi)圖)

3) 代碼實(shí)現(xiàn)

package com.lin.Visitor;

public abstract class Person {

    // 提供一個(gè)方法讓訪(fǎng)問(wèn)者可以訪(fǎng)問(wèn)
    public abstract void accept(Action action);
}
package com.lin.Visitor;

//1. 這里我們使用到了雙分派,  即首先在客戶(hù)端程序中,將具體狀態(tài)作為參數(shù)傳遞 Woman 中(第一次分派)

//2. 然后 Woman 類(lèi)調(diào)用作為參數(shù)的 "具體方法" 中方法 getWomanResult, 同時(shí)將自己(this)作為參數(shù)

// 傳入,完成第二次的分派

public class Women extends Person{

    @Override
    public void accept(Action action) {
        action.getWomenResult(this);
        
    }

}
package com.lin.Visitor;

public class Man extends Person{

    @Override
    public void accept(Action action) {
        action.getManResult(this);
        
    }

}
package com.lin.Visitor;

public abstract class Action {

    // 得到男性的測(cè)評(píng)
    public abstract void getManResult(Person person);
    
    // 得到女性的測(cè)評(píng)
    public abstract void getWomenResult(Person person);
    
}
package com.lin.Visitor;

public class Success extends Action {

    @Override
    public void getManResult(Person person) {
        System.out.println("男性觀(guān)眾給的評(píng)價(jià)是成功!");

    }

    @Override
    public void getWomenResult(Person person) {
        System.out.println("女性觀(guān)眾給的評(píng)價(jià)是成功!");

    }

}
package com.lin.Visitor;

public class Fail extends Action {

    @Override
    public void getManResult(Person person) {
        System.out.println("男性觀(guān)眾給的評(píng)價(jià)是失??!");

    }

    @Override
    public void getWomenResult(Person person) {
        System.out.println("女性觀(guān)眾給的評(píng)價(jià)是失??!");

    }

}
package com.lin.Visitor;

import java.util.LinkedList;
import java.util.List;

public class ObjectStructure {

    private List<Person> persons = new LinkedList<>();
    // 添加
    public void attach(Person person) {
        persons.add(person);
    }
    // 移除
    public void detach(Person person) {
        persons.remove(person);
    }
    // 顯示
    public void display(Action action) {
        for (Person person : persons) {
            person.accept(action);
        }
    }
}
package com.lin.Visitor;

public class Client {

    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        
        objectStructure.attach(new Women());
        objectStructure.attach(new Man());
        objectStructure.attach(new Women());
        objectStructure.attach(new Man());
        
        Success success = new Success();
        objectStructure.display(success);
        System.out.println("==========================");
        Wait wait = new Wait();
        objectStructure.display(wait);
    }
}

4) 應(yīng)用案例的小結(jié)-雙分派

-上面提到了雙分派,所謂雙分派是指不管類(lèi)怎么變化,我們都能找到期望的方法運(yùn)行。雙分派意味著得到執(zhí)行的操作取決于請(qǐng)求的種類(lèi)和兩個(gè)接收者的類(lèi)型

- 以上述實(shí)例為例,假設(shè)我們要添加一個(gè) Wait 的狀態(tài)類(lèi),考察 Man 類(lèi)和 Woman 類(lèi)的反應(yīng),由于使用了雙分派,只需增加一個(gè) Action 子類(lèi)即可在客戶(hù)端調(diào)用即可,不需要改動(dòng)任何其他類(lèi)的代碼。

6 訪(fǎng)問(wèn)者模式的注意事項(xiàng)和細(xì)節(jié)

  • 優(yōu)點(diǎn)

1) 訪(fǎng)問(wèn)者模式符合單一職責(zé)原則、讓程序具有優(yōu)秀的擴(kuò)展性、靈活性非常高

2) 訪(fǎng)問(wèn)者模式可以對(duì)功能進(jìn)行統(tǒng)一,可以做報(bào)表、UI、攔截器與過(guò)濾器,適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的系統(tǒng)

  • 缺點(diǎn)

1) 具體元素對(duì)訪(fǎng)問(wèn)者公布細(xì)節(jié),也就是說(shuō)訪(fǎng)問(wèn)者關(guān)注了其他類(lèi)的內(nèi)部細(xì)節(jié),這是迪米特法則所不建議的, 這樣造成了具體元素變更比較困難

2) 違背了依賴(lài)倒轉(zhuǎn)原則。訪(fǎng)問(wèn)者依賴(lài)的是具體元素,而不是抽象元素

3) 因此,如果一個(gè)系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),又有經(jīng)常變化的功能需求,那么訪(fǎng)問(wèn)者模式就是比較合適的.

 

僅供參考,有錯(cuò)誤還請(qǐng)指出!

有什么想法,評(píng)論區(qū)留言,互相指教指教。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多