本篇內(nèi)容主要講解“行為型模式有哪些內(nèi)容”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“行為型模式有哪些內(nèi)容”吧!
創(chuàng)新互聯(lián)公司成立于2013年,我們提供高端重慶網(wǎng)站建設(shè)公司、成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、網(wǎng)站定制、網(wǎng)絡(luò)營(yíng)銷推廣、小程序開發(fā)、微信公眾號(hào)開發(fā)、seo優(yōu)化排名服務(wù),提供專業(yè)營(yíng)銷思路、內(nèi)容策劃、視覺設(shè)計(jì)、程序開發(fā)來完成項(xiàng)目落地,為成都木屋企業(yè)提供源源不斷的流量和訂單咨詢。
責(zé)任鏈模式可以拆分為責(zé)任和鏈,責(zé)任是指有責(zé)任去干嘛,鏈可以參考鏈表嘛,有下一級(jí)。
場(chǎng)景:現(xiàn)在你是某公司的員工,拿到了一個(gè)比較緊急的文件(文件的緊急性肯定不一樣嘛),需要更高一層的領(lǐng)導(dǎo)來處理下文件。
文件類:
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類給暴露出來了,而且是在Client中才進(jìn)行判斷不同等級(jí)給不同的領(lǐng)導(dǎo)處理。
通俗地比喻呢,就是員工拿到了文件后,把自己的組長(zhǎng),總監(jiān),主管全都叫到自己跟前,然后說,這份文件是比較重要的,給你們誰(shuí)處理才有權(quán)限。確實(shí)是可以完成人物,但是這樣的方式現(xiàn)實(shí)嗎?
接近現(xiàn)實(shí)的一種方式是怎么樣的呢,員工拿到文件后,首先給自己的直接領(lǐng)導(dǎo)組長(zhǎng),在領(lǐng)導(dǎo)層(handler)中的最低的一層(鏈頭)。接著組長(zhǎng)再看自己有沒有責(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; } //沒有責(zé)任,交給下一級(jí) public void setNextHandler(AbstractHandler nextHandler) { this.nextHandler = nextHandler; } //處理回應(yīng),每個(gè)人的回應(yīng)方式不一樣,所以抽象出來 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)限!?。?quot;); } } } }
組長(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):**處理和請(qǐng)求分開,員工不知道最終文件是誰(shuí)處理的
**缺點(diǎn):**缺點(diǎn)也十分明顯,如果責(zé)任鏈很長(zhǎng),而處理者剛好在最后,是不是要遍歷完責(zé)任鏈。這樣性能就比較低,在實(shí)際使用中,一般會(huì)折這一個(gè)最大鏈長(zhǎng)來保證性能。
命令模式,一句話就是給你一個(gè)命令,必須要遵守并且執(zhí)行,有點(diǎn)像是軍隊(duì)里面“服從命令是軍人的天職”。
不知道大學(xué)有沒有參加過數(shù)學(xué)建模,反正我是沒有參加過,但是有了解過一般構(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 開始搜索相關(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 開始寫論文"); } }
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 開始碼代碼"); } }
Teacher:
public class NTeacher { public static void main(String[] args) { NTeammate writer = new NWriter(); //需要改文章了 writer.modify(); writer.work(); } }
一開始,老師看到寫的文展不夠簡(jiǎn)潔,所以就打電話給writer,讓他修改,所以就有了上面的Teacher類。這樣其實(shí)還好,因?yàn)槲恼侣铮薷臐?rùn)色就好了。
過了一天,老師仔細(xì)看了下后,發(fā)現(xiàn)代碼的算法有bug,這個(gè)漏洞導(dǎo)致了不僅coder要修改代碼,writer也要修改相應(yīng)地方的文章。
老師這下不僅要聯(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ì)想到利用中介者模式,不過中介者模式是為了減小類和類之間的耦合,這個(gè)例子中的searcher,writer,coder并沒有耦合,都在各司其職。
如果小隊(duì)里面有個(gè)隊(duì)長(zhǎng)(Invoker)就好了,可以和老師(client)溝通,不止這樣,老師的指令實(shí)現(xiàn)起來肯定是String類型,我們可以把指令封裝稱一個(gè)類(command),隊(duì)長(zhǎng)只需要發(fā)布命令,命令指示隊(duì)員(receiver)來做什么。這就是命令模式,隊(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):
有哪些命令,都可以封裝起來
改變需求:
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(); } }
如果老師覺得又不好了,這些怎么辦呢,沒有必要和成員練習(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(); } }
如果說,誒,改代碼的時(shí)候不僅需要修改bug和修正文章,也需要searcher來搜集信息,怎么辦呢?
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ù)來撤銷動(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(); } }
這個(gè)無論是工作上還是學(xué)習(xí)中都是比較冷門的設(shè)計(jì)模式。解釋器模式由以下類組成
Context:Context用于封裝解釋器的全局信息,所有具體的解釋器均需要訪問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è)東西解釋起來比較拗口,一時(shí)也沒有很好的通俗的解釋,那就直接看例子叭。
public interface Expression { public float interpret(); }
public class Number implements Expression{ private final float number; public Number(float number) { this.number = number; } @Override public float interpret() { return number; } }
還記得之前說過的流嗎,TerminalExpression
就類似終結(jié)操作,而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(); } }
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("-"); } }
到此,相信大家對(duì)“行為型模式有哪些內(nèi)容”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
分享題目:行為型模式有哪些內(nèi)容
本文地址:http://chinadenli.net/article42/jdpohc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、網(wǎng)站設(shè)計(jì)公司、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站策劃、企業(yè)網(wǎng)站制作、網(wǎng)站內(nèi)鏈
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)