日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式

發(fā)布時間:2024/3/7 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

命令模式

  • 示例
    • 改進(jìn)代碼
  • 命令模式
    • 定義
    • 意圖
    • 主要解決問題
    • 何時使用
    • 優(yōu)缺點(diǎn)
  • 玉帝傳美猴王上天
  • 命令模式和策略模式的區(qū)別

示例

系統(tǒng)需要設(shè)計(jì)一個命令行界面,用戶可輸入命令來執(zhí)行某項(xiàng)功能,系統(tǒng)的功能會不斷增加,命令也會不斷的增加
如何將一項(xiàng)一項(xiàng)的功能加入到這個命令行界面?
如何讓命令行程序?qū)懞煤?#xff0c;不因功能的添加而修改,又可以靈活的加入命令和功能?
下面以奶茶店售賣奶茶為例:

public class MashedTaroMilk {public void build() {System.out.println("奶茶師傅制作芋泥啵啵奶茶。。。");} } public class StrawBerryMilk {public void build() {System.out.println("奶茶師傅制作草莓奶茶。。。");} }

服務(wù)員類:負(fù)責(zé)接待顧客售賣奶茶

public class Waiter {public void receiver(String command) {System.out.println("您選擇了:" + command);switch (command) {case "芋泥啵啵奶茶" :new MashedTaroMilk().build();break;case "草莓奶茶" :new StrawBerryMilk().build();break;default :System.out.println("您點(diǎn)的奶茶本店沒有。。。");break;}}public void showMenu() {System.out.println("您好,本店有以下奶茶:");System.out.println("\t芋泥啵啵奶茶");System.out.println("\t草莓奶茶");} }

測試類:

public class Client {public static void main(String[] args) {waiter();}public static void waiter() {Waiter waiter = new Waiter();waiter.showMenu();Scanner scanner = new Scanner(System.in);System.out.println("請選擇:");String chooseMilk = scanner.nextLine();waiter.receiver(chooseMilk);scanner.close();} }


現(xiàn)在如果奶茶增加了呢,需要對服務(wù)員類中的switch語句進(jìn)行修改,但是又不想修改,該怎么做呢

改進(jìn)代碼

定義一個制作奶茶的接口,所有的奶茶實(shí)現(xiàn)它:

public interface Command {/** 制作奶茶接口 */void build(); }

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

public class AppleMilk implements Command {@Overridepublic void build() {System.out.println("開始制作蘋果奶茶。。。");} } public class PlainMilk implements Command {@Overridepublic void build() {System.out.println("開始制作原味奶茶。。。");} }

現(xiàn)在又招了一個女服務(wù)員,負(fù)責(zé)接待:

public class Waitress {private Map<String, Command> map = new HashMap<>();public void addMilk(String name, Command command) {map.put(name, command);}public void receiver(String command) {System.out.println("您選擇了:" + command);Command command1 = map.get(command);if (command1 != null) {command1.build();} else {System.out.println("您點(diǎn)的奶茶本店沒有。。。");}}public void showMenu() {System.out.println("您好,本店有以下奶茶:");map.keySet().forEach((item)->{System.out.println("\t" + item);});} }

測試類:

public class Client {public static void main(String[] args) {waitress();}public static void waitress() {Waitress waitress = new Waitress();waitress.addMilk("蘋果奶茶", new AppleMilk());waitress.addMilk("原味奶茶", new PlainMilk());waitress.showMenu();Scanner scanner = new Scanner(System.in);System.out.println("請選擇:");String chooseMilk = scanner.nextLine();waitress.receiver(chooseMilk);scanner.close();} }


上面改進(jìn)之后,每增加一個新的奶茶,只需要實(shí)現(xiàn)接口即可

命令模式

定義

以命令的方式,解耦調(diào)用者和功能的具體實(shí)現(xiàn)者,降低了系統(tǒng)的耦合度,提高了靈活性

意圖

將一個請求封裝成一個對象,從而使您可以用不同的請求對客戶進(jìn)行參數(shù)化

主要解決問題

在軟件系統(tǒng)中,行為請求者與行為實(shí)現(xiàn)者通常是一種緊耦合的關(guān)系,但某些場合,比如需要對行為進(jìn)行記錄、撤銷或重做、事務(wù)等處理時,這種無法抵御變化的緊耦合的設(shè)計(jì)就不太合適

何時使用

在某些場合,比如要對行為進(jìn)行"記錄、撤銷/重做、事務(wù)"等處理,這種無法抵御變化的緊耦合是不合適的。在這種情況下,如何將"行為請求者"與"行為實(shí)現(xiàn)者"解耦?將一組行為抽象為對象,可以實(shí)現(xiàn)二者之間的松耦合

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

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

  • 降低了系統(tǒng)的耦合度
  • 提高了靈活性
  • 缺點(diǎn):
    使用命令模式可能會導(dǎo)致某些系統(tǒng)有過多的具體命令類

    類圖:

    涉及的角色:

  • 客戶(Client)角色:創(chuàng)建了一個具體命令(ConcreteCommand)對象并確定其接收者
  • 命令(Command)角色:聲明了一個給所有具體命令類的抽象接口,通常由接口或者抽象類實(shí)現(xiàn)
  • 具體命令(ConcreteCommand)角色:定義一個接收者和行為之間的弱耦合;實(shí)現(xiàn)execute()方法,負(fù)責(zé)調(diào)用接收者的相應(yīng)操作,execute()方法通常叫做執(zhí)行方法
  • 請求者(Invoker)角色:負(fù)責(zé)調(diào)用命令對象執(zhí)行請求,相關(guān)的方法叫做行動方法
  • 接收者(Receiver)角色:負(fù)責(zé)具體實(shí)施和執(zhí)行一個請求,任何一個類都可以成為接收者,實(shí)施和執(zhí)行請求的方法叫做行動方法
  • 對應(yīng)的類如下:
    Client類:

    public class Client {public static void main(String[] args) {Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker(command);invoker.action();} }

    Command接口:

    public interface Command {/** 執(zhí)行方法 */void execute(); }

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

    public class ConcreteCommand implements Command {private Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println("do something......");receiver.action();} }

    Invoker類:

    public class Invoker {private Command command;public Invoker(Command command) {this.command = command;}/** 行動方法 */public void action() {command.execute();} }

    Receiver類:

    public class Receiver {public Receiver() {}/** 行動方法 */public void action() {} }

    玉帝傳美猴王上天

    在美猴王大鬧天宮之前,玉帝命令太白金星召美猴王上天,玉帝的這一道旨意就是一個命令,而太白金星則是負(fù)責(zé)將圣旨傳到,具體的執(zhí)行者則是美猴王:
    抽象接口,所有的圣旨都需要實(shí)現(xiàn)它:

    public interface ImperialEdictCommand {/** 抽象圣旨,具體圣旨都必須具備的接口 */void command(); }

    具體的命令,即召美猴王上天這一個具體的圣旨:

    public class SkyReportsConcreteCommand implements ImperialEdictCommand {private MonkeyKingReceiver receiver;public SkyReportsConcreteCommand(MonkeyKingReceiver receiver) {this.receiver = receiver;}@Overridepublic void command() {System.out.println("宣美猴王孫悟空上天報(bào)道!");receiver.action();} }

    玉皇大帝,頒布圣旨:

    public class TheJadeEmperorClient {public static void main(String[] args) {System.out.println("玉皇大帝頒布一道圣旨,宣美猴王上天報(bào)道!");MonkeyKingReceiver receiver = new MonkeyKingReceiver();ImperialEdictCommand command = new SkyReportsConcreteCommand(receiver);GreatWhitePlanetInvoker invoker = new GreatWhitePlanetInvoker();invoker.setCommand(command);invoker.action();} }

    太白金星負(fù)責(zé)把旨意傳達(dá)給美猴王:

    public class GreatWhitePlanetInvoker {private ImperialEdictCommand command;public void setCommand(ImperialEdictCommand command) {this.command = command;}/** 請求者太白金星調(diào)用此方法,要求美猴王上天 */public void action() {System.out.println("太白金星傳玉帝圣旨!");command.command();} }

    具體的執(zhí)行者,就是美猴王:

    public class MonkeyKingReceiver {public MonkeyKingReceiver() {}public void action() {System.out.println("美猴王孫悟空上天,大鬧天宮!");} }


    類圖:

    命令模式和策略模式的區(qū)別

    命令模式的結(jié)構(gòu)如下:

    策略模式的結(jié)構(gòu)如下:

    策略模式:側(cè)重的是一個行為的多個算法實(shí)現(xiàn),可互換算法,比如優(yōu)惠活動滿減和打折都是算法,可以選擇其中一個來買買買

    命令模式:側(cè)重的是為多個行為提供靈活的執(zhí)行方式,比如上面的奶茶,每個顧客購買奶茶的命令都是一個行為,而不同的奶茶制作方式不一樣,則就需要靈活的去制作奶茶

    總結(jié)

    以上是生活随笔為你收集整理的玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。