溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

行為型模式有哪些內(nèi)容

發(fā)布時(shí)間:2021-10-12 14:34:32 來(lái)源:億速云 閱讀:123 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“行為型模式有哪些內(nèi)容”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“行為型模式有哪些內(nèi)容”吧!

責(zé)任鏈模式

責(zé)任鏈模式可以拆分為責(zé)任和鏈,責(zé)任是指有責(zé)任去干嘛,鏈可以參考鏈表嘛,有下一級(jí)。

場(chǎng)景:現(xiàn)在你是某公司的員工,拿到了一個(gè)比較緊急的文件(文件的緊急性肯定不一樣嘛),需要更高一層的領(lǐng)導(dǎo)來(lái)處理下文件。

普通模式

文件類:

public class File {

    private FileClass fileClass;	//文件的重要等級(jí)
    private String content;			//文件的內(nèi)容

    //省略

}

//枚舉類表示文件的重要等級(jí)
enum FileClass {
    NORMAL,
    IMPORTANT,
    EMERGENCY
}

員工接口:

public interface IStaff {
    //獲取員工的名字
    public String getName();
    
    //獲取要處理文件的等級(jí)
    public FileClass getFileClass();
    
    //獲取員工的需求
    public String getRequest();    
}

員工:

public class Staff implements IStaff {
    private File file;
    private String name;

	//省略構(gòu)造函數(shù)

    @Override
    public String getName() {
        return name;
    }

    @Override
    public FileClass getFileClass() {
        return file.getFileClass();
    }

    @Override
    public String getRequest() {
        return "這份文件【" + file.getContent() +"】需要處理下";
    }
}

領(lǐng)導(dǎo)接口:

public interface IHandler {
    //處理文件
    public void handle(IStaff staff);
}

組長(zhǎng):

public class Leader implements IHandler {
    @Override
    public void handle(IStaff staff) {
        System.out.println(staff.getName() + ": " + staff.getRequest());
        System.out.println("組長(zhǎng):現(xiàn)在處理");
    }
}

總監(jiān):

public class Director implements IHandler{
    @Override
    public void handle(IStaff staff) {
        System.out.println(staff.getName() + ": " + staff.getRequest());
        System.out.println("總監(jiān):現(xiàn)在處理");
    }
}

主管:

public class Supervisor implements IHandler {
    @Override
    public void handle(IStaff staff) {
        System.out.println(staff.getName() + ": " + staff.getRequest());
        System.out.println("主管:現(xiàn)在處理");
    }
}

Client:

public class Client {
    public static void main(String[] args) {
        File file = new File(FileClass.IMPORTANT, "策劃方案");
        IStaff staff = new Staff(file, "imperfect");
        
        if(file.getFileClass().equals(FileClass.NORMAL)) {
            new Leader().handle(staff);
        } else if(file.getFileClass().equals(FileClass.IMPORTANT)) {
            new Director().handle(staff);
        } else if(file.getFileClass().equals(FileClass.EMERGENCY)) {
            new Supervisor().handle(staff);
        } else {
            System.out.println("權(quán)限不夠");
        }
        
    }
}

你瞅瞅,仔細(xì)品,這一堆if else直接在Client類給暴露出來(lái)了,而且是在Client中才進(jìn)行判斷不同等級(jí)給不同的領(lǐng)導(dǎo)處理。

通俗地比喻呢,就是員工拿到了文件后,把自己的組長(zhǎng),總監(jiān),主管全都叫到自己跟前,然后說(shuō),這份文件是比較重要的,給你們誰(shuí)處理才有權(quán)限。確實(shí)是可以完成人物,但是這樣的方式現(xiàn)實(shí)嗎?

行為型模式有哪些內(nèi)容

接近現(xiàn)實(shí)的一種方式是怎么樣的呢,員工拿到文件后,首先給自己的直接領(lǐng)導(dǎo)組長(zhǎng),在領(lǐng)導(dǎo)層(handler)中的最低的一層(鏈頭)。接著組長(zhǎng)再看自己有沒(méi)有責(zé)任去處理文件,沒(méi)有的話再給下一層來(lái)處理,這就是責(zé)任鏈模式。

責(zé)任鏈模式

文件類和員工類不變,主要是領(lǐng)導(dǎo)層(handler)的變化。

抽象領(lǐng)導(dǎo)類:

public abstract class AbstractHandler {
    private FileClass fileClass;
    private AbstractHandler nextHandler;
    private String name;

    //在類構(gòu)造的時(shí)候就明確了職責(zé)
    //就像你入職就知道自己的責(zé)任是處理什么文件
    public AbstractHandler(FileClass fileClass, String name) {
        this.fileClass = fileClass;
        this.name = name;
    }

    //取得領(lǐng)導(dǎo)的名字
    public String getName() {
        return name;
    }

    //沒(méi)有責(zé)任,交給下一級(jí)
    public void setNextHandler(AbstractHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    //處理回應(yīng),每個(gè)人的回應(yīng)方式不一樣,所以抽象出來(lái)
    public abstract void respond(IStaff staff);

    //處理信息
    public void handle(IStaff staff) {
        if(fileClass.equals(staff.getFileClass())) {
            respond(staff);
        } else {
            if(nextHandler != null) {
                nextHandler.respond(staff);
            } else {
                System.out.println("已經(jīng)到最高權(quán)限?。?!");
            }
        }
    }

}

組長(zhǎng):

public class Leader extends AbstractHandler {

    public Leader(String name) {
        super(FileClass.NORMAL, name);
    }

    @Override
    public void respond(IStaff staff) {
        System.out.println(staff.getName() + ": " + staff.getRequest());
        System.out.println(getName() + "組長(zhǎng):做出了回應(yīng)");
    }
}

總監(jiān):

public class Director extends AbstractHandler{

    public Director(String name) {
        super(FileClass.IMPORTANT, name);
    }

    @Override
    public void respond(IStaff staff) {
        System.out.println(staff.getName() + ": " + staff.getRequest());
        System.out.println(getName() + "總監(jiān):做出了回應(yīng)");
    }
}

主管:

public class Supervisor extends AbstractHandler {

    public Supervisor(String name) {
        super(FileClass.EMERGENCY, name);
    }

    @Override
    public void respond(IStaff staff) {
        System.out.println(staff.getName() + ": " + staff.getRequest());
        System.out.println(getName() + "主管:做出了回應(yīng)");
    }
}

Client:

public class Client {
    public static void main(String[] args) {
        File file = new File(FileClass.IMPORTANT, "營(yíng)銷方案");
        IStaff staff = new Staff(file, "imperfect");

        //創(chuàng)建領(lǐng)導(dǎo)層
        AbstractHandler leader = new Leader("leaderWu");
        AbstractHandler director = new Director("directorWu");
        AbstractHandler supervisor = new Supervisor("supervisorWu");

        //設(shè)置層級(jí)關(guān)系,跟鏈表類似
        leader.setNextHandler(director);
        director.setNextHandler(supervisor);

        //首先交給直接領(lǐng)導(dǎo)處理
        leader.handle(staff);
        
    }
}

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

  • **優(yōu)點(diǎn):**處理和請(qǐng)求分開(kāi),員工不知道最終文件是誰(shuí)處理的

  • **缺點(diǎn):**缺點(diǎn)也十分明顯,如果責(zé)任鏈很長(zhǎng),而處理者剛好在最后,是不是要遍歷完責(zé)任鏈。這樣性能就比較低,在實(shí)際使用中,一般會(huì)折這一個(gè)最大鏈長(zhǎng)來(lái)保證性能。

UML類圖

行為型模式有哪些內(nèi)容

命令模式

命令模式,一句話就是給你一個(gè)命令,必須要遵守并且執(zhí)行,有點(diǎn)像是軍隊(duì)里面“服從命令是軍人的天職”。

不知道大學(xué)有沒(méi)有參加過(guò)數(shù)學(xué)建模,反正我是沒(méi)有參加過(guò),但是有了解過(guò)一般構(gòu)成,一個(gè)小隊(duì)里面一般有主要負(fù)責(zé)搜索的同學(xué),寫代碼的同學(xué),寫論文的同學(xué)和指導(dǎo)老師

普通模式

抽象成員類(receiver):

public abstract class NTeammate {

    public abstract void changeRequire();

    public abstract void modify();

    public abstract void work();

}

Searcher:

public class NSearcher extends NTeammate {
    @Override
    public void changeRequire() {
        System.out.println("searcher 了解到需求改變");
    }

    @Override
    public void modify() {

    }

    @Override
    public void work() {
        System.out.println("searcher 開(kāi)始搜索相關(guān)信息");
    }
}

Writer:

public class NWriter extends NTeammate {
    @Override
    public void changeRequire() {
        System.out.println("writer 了解到需求改變");
    }

    @Override
    public void modify() {
        System.out.println("writer 修改論文");
    }

    @Override
    public void work() {
        System.out.println("writer 開(kāi)始寫論文");
    }
}

Coder:

public class NCoder extends NTeammate {
    @Override
    public void changeRequire() {
        System.out.println("coder 了解到需求改變");
    }

    @Override
    public void modify() {
        System.out.println("coder 修改代碼");
    }

    @Override
    public void work() {
        System.out.println("coder 開(kāi)始碼代碼");
    }
}

Teacher:

public class NTeacher {
    public static void main(String[] args) {
        NTeammate writer = new NWriter();
        //需要改文章了
        writer.modify();
        writer.work();
    }
}

一開(kāi)始,老師看到寫的文展不夠簡(jiǎn)潔,所以就打電話給writer,讓他修改,所以就有了上面的Teacher類。這樣其實(shí)還好,因?yàn)槲恼侣?,修改?rùn)色就好了。

過(guò)了一天,老師仔細(xì)看了下后,發(fā)現(xiàn)代碼的算法有bug,這個(gè)漏洞導(dǎo)致了不僅coder要修改代碼,writer也要修改相應(yīng)地方的文章。

行為型模式有哪些內(nèi)容

老師這下不僅要聯(lián)系writer,也得聯(lián)系coder,那么Teacher類應(yīng)該怎么修改呢?

public class NTeacher {
    public static void main(String[] args) {
        NTeammate writer = new NWriter();
        NTeammate coder = new NCoder();
        //需要改bug和文章了
        writer.modify();
        writer.work();
        
        coder.modify();
        coder.work();
        
    }
}

可以發(fā)現(xiàn),就多了一個(gè)需求,代碼較之前已經(jīng)有很大的改動(dòng)了,這是我們不希望看到的??赡苡械男』锇闀?huì)想到利用中介者模式,不過(guò)中介者模式是為了減小類和類之間的耦合,這個(gè)例子中的searcher,writer,coder并沒(méi)有耦合,都在各司其職。

命令模式

如果小隊(duì)里面有個(gè)隊(duì)長(zhǎng)(Invoker)就好了,可以和老師(client)溝通,不止這樣,老師的指令實(shí)現(xiàn)起來(lái)肯定是String類型,我們可以把指令封裝稱一個(gè)類(command),隊(duì)長(zhǎng)只需要發(fā)布命令,命令指示隊(duì)員(receiver)來(lái)做什么。這就是命令模式,隊(duì)員必須執(zhí)行命令要求做的。

抽象隊(duì)員以及具體隊(duì)員還是和上面一樣,這里就不再贅述。

抽象命令類:

public abstract class AbstractCommand {
    protected Coder coder = new Coder();
    protected Searcher searcher = new Searcher();
    protected Writer writer = new Writer();
    
    //一定要有個(gè)執(zhí)行的方法,下達(dá)一個(gè)命令
    public abstract void execute();
}

具體命令類(Command):

有哪些命令,都可以封裝起來(lái)

改變需求:

public class ChangeInfoCommand extends AbstractCommand {
    @Override
    public void execute() {
        searcher.changeRequire();
        writer.changeRequire();
        coder.changeRequire();
    }
}

修改文章:

public class ModifyArticleCommand extends AbstractCommand {
    @Override
    public void execute() {
        writer.modify();
        writer.work();
    }
}

修改代碼:

public class ModifyCodeCommand extends AbstractCommand {
    @Override
    public void execute() {
        coder.modify();
        coder.work();
        writer.modify();
        writer.work();
    }
}

隊(duì)長(zhǎng)類(Invoke):

public class Captain {
    //和命令產(chǎn)生聯(lián)系
    AbstractCommand abstractCommand;

    public Captain(AbstractCommand abstractCommand) {
        this.abstractCommand = abstractCommand;
    }

    public void invoke() {
        //發(fā)布命令要求隊(duì)員進(jìn)行相應(yīng)的動(dòng)作
        abstractCommand.execute();
    }

}

老師類(Client):

public class Teacher {
    public static void main(String[] args) {
        AbstractCommand command = new ModifyCodeCommand();
        Captain captain = new Captain(command);
        captain.invoke();
    }
}

如果老師覺(jué)得又不好了,這些怎么辦呢,沒(méi)有必要和成員練習(xí),只需要提出另外一個(gè)建議,隊(duì)長(zhǎng)也不要跟隊(duì)員練習(xí),只需要發(fā)布命令,由命令指示隊(duì)員去做。修改就是這么簡(jiǎn)單,一行代碼的事情。

public class Teacher {
    public static void main(String[] args) {
        //AbstractCommand command = new ModifyCodeCommand();
        AbstractCommand command = new ModifyArticleCommand();
        Captain captain = new Captain(command);
        captain.invoke();
    }
}

擴(kuò)展

如果說(shuō),誒,改代碼的時(shí)候不僅需要修改bug和修正文章,也需要searcher來(lái)搜集信息,怎么辦呢?

public class ModifyCodeCommand extends AbstractCommand {
    @Override
    public void execute() {
        searcher.work();	//只需要在具體的命令里面添加即可,客戶端是完全不知道的
        coder.modify();
        coder.work();
        writer.modify();
        writer.work();
    }
}

還有一種情況就是,某些修改之后,老師發(fā)現(xiàn)還是之前的版本比較好,這就要求每個(gè)隊(duì)員都有一個(gè)回調(diào)函數(shù)來(lái)撤銷動(dòng)作,返回到上一個(gè)狀態(tài),就是找到保存的之前版本的文件。只需要在抽象receiver類加一個(gè)回調(diào)函數(shù)即可

public abstract class NTeammate {

    public abstract void changeRequire();

    public abstract void modify();

    public abstract void work();
    
    //具體隊(duì)友在根據(jù)自己的方式實(shí)現(xiàn)回調(diào)方法
    public abstract void rollback();

}

接著就是添加一個(gè)撤回命令

public class callBackCommand extends AbstractCommand {
    @Override
    public void execute() {
        //當(dāng)然,需要誰(shuí)撤回是可以改變的
        searcher.rollback();
        writer.rollback();
        coder.rollback();
    }
}

UML類圖

行為型模式有哪些內(nèi)容

解釋器模式

這個(gè)無(wú)論是工作上還是學(xué)習(xí)中都是比較冷門的設(shè)計(jì)模式。解釋器模式由以下類組成

  • Context: Context用于封裝解釋器的全局信息,所有具體的解釋器均需要訪問(wèn)Context。

  • AbstractExpression: 一個(gè)抽象類或接口,聲明執(zhí)行的解釋方法,由所有具體的解釋器實(shí)現(xiàn)

  • TerminalExpression: 一種解釋器類,實(shí)現(xiàn)與語(yǔ)法的終結(jié)符相關(guān)的操作。終結(jié)符表達(dá)式必須終結(jié)被實(shí)現(xiàn)和實(shí)例化,因?yàn)樗硎颈磉_(dá)式的結(jié)尾。

  • NonTerminalExpreesion: 這是實(shí)現(xiàn)語(yǔ)法的不同規(guī)則或符號(hào)的類。對(duì)于每一種語(yǔ)法都應(yīng)該創(chuàng)建一個(gè)類。

這個(gè)東西解釋起來(lái)比較拗口,一時(shí)也沒(méi)有很好的通俗的解釋,那就直接看例子叭。

AbstractExpression

public interface Expression {
    public float interpret();
}

TerminalExpression

public class Number implements Expression{
    private final float number;

    public Number(float number) {
        this.number = number;
    }

    @Override
    public float interpret() {
        return number;
    }
}

還記得之前說(shuō)過(guò)的流嗎,TerminalExpression 就類似終結(jié)操作,而NonTerminalExpression 就是類似中間操作

NonTerminalExpression

public class Plus implements Expression{
    Expression left;
    Expression right;

    public Plus(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public float interpret() {
        return left.interpret() + right.interpret();
    }
}

注意對(duì)于每一個(gè)語(yǔ)法都要有一個(gè)獨(dú)立的類

public class Minus implements Expression {
    Expression left;
    Expression right;

    public Minus(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public float interpret() {
        return left.interpret() - right.interpret();
    }
}

Context

public class Evaluator {

    public static void main(String[] args) {
        Evaluator evaluator = new Evaluator();
        System.out.println(evaluator.evaluate("3 4 +"));
        System.out.println(evaluator.evaluate("4 3 -"));
        System.out.println(evaluator.evaluate("4 3 - 2 +"));
    }


    public float evaluate(String expression) {
        Stack<Expression> stack = new Stack<>();
        float result = 0;
        for (String token : expression.split(" ")) {
            Expression exp = null;
            if (isOperator(token)) {
                if (token.equals("+")) {
                    exp = stack.push(new Plus(stack.pop(), stack.pop()));
                } else if (token.equals("-")) {
                    exp = stack.push(new Minus(stack.pop(), stack.pop()));
                }

                if (null != exp) {
                    result = exp.interpret();
                    stack.push(new Number(result));
                }
            }

            if (isNumber(token)) {
                stack.push(new Number(Float.parseFloat(token)));
            }
        }
        return result;
    }

    private boolean isNumber(String token) {
        try {
            Float.parseFloat(token);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private boolean isOperator(String token) {
        return token.equals("+") || token.equals("-");
    }
    
}

UML類圖

行為型模式有哪些內(nèi)容

到此,相信大家對(duì)“行為型模式有哪些內(nèi)容”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI