前提
介紹這么模式之前,我們首先來(lái)看看它的類圖惠呼。
根據(jù)這個(gè)圖我們來(lái)分析一下何為命令模式滋早。首先就是我們的 Client
想要實(shí)現(xiàn)一個(gè)功能,于是它就創(chuàng)建了一個(gè) Command
考婴, 為了方便調(diào)用將 Command
封裝在了 Invoker
中贩虾,當(dāng)我們想調(diào)用的時(shí)候,Invoker
會(huì)執(zhí)行內(nèi)部 Command
提供的方法, Receiver
接收到 Command
的請(qǐng)求沥阱,為其提供底部支持缎罢。
多說(shuō)無(wú)益,我將通過(guò)一個(gè)例子介紹命令模式考杉。
實(shí)例
目前大部分的軟件都支持用戶自定義界面策精,比如說(shuō)我們可以修改字體大小,背景顏色等崇棠。我們就以此為例咽袜。首先,寫出兩個(gè)類枕稀。
public class Font {
private String fontSize = "normal";
public String getFontSize() {
return fontSize;
}
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
}
public class Background {
private String bgColor = "white";
public String getBgColor() {
return bgColor;
}
public void setBgColor(String bgColor) {
this.bgColor = bgColor;
}
}
以上這兩個(gè)類在命令模式的類圖中扮演的是 Receiver
角色询刹,提供底層支持谜嫉。
public interface Command {
public void execute();
}
這是 Command
, 修改字體大小和背景的類都繼承于此。
public class NormalFontCommand implements Command {
private Font font;
public NormalFontCommand(Font font) {
this.font = font;
}
@Override
public void execute() {
font.setFontSize("Normal");
}
}
public class LargeFontCommand implements Command {
private Font font;
public LargeFontCommand(Font font) {
this.font = font;
}
@Override
public void execute() {
font.setFontSize("Large");
}
}
很簡(jiǎn)單的凹联,我們只是在類中獲得一個(gè) Font
類的引用沐兰,然后調(diào)用setFontSize()
方法對(duì)字體的大小進(jìn)行設(shè)置。
因?yàn)楸尘邦伾姆N類特別多匕垫,如果我們針對(duì)每種顏色都編寫一個(gè)類僧鲁,那就太不實(shí)際了。所以我們決定用兩個(gè)類去實(shí)現(xiàn)它象泵,一個(gè)類表示是默認(rèn)顏色寞秃,一個(gè)是類表示非默認(rèn)顏色。
public class DefaultBackground implements Command {
private Background background;
public DefaultBackground(Background background) {
this.background = background;
}
@Override
public void execute() {
background.setBgColor("Default color");
}
}
public class CustomBackground implements Command {
private Background background;
private String color = null;
public CustomBackground(Background background) {
this.background = background;
}
@Override
public void execute() {
background.setBgColor("Custom background");
}
}
好了偶惠,通過(guò)以上操作春寿,我們不僅定義好了 Command
,還定義了 Receiver
類,下面就差 Invoker
類了忽孽。
public class Invoker {
private ArrayList<Command> commands;
public Invoker() {
commands = new ArrayList<>();
}
public void setCommand(int i, Command command) {
commands.add(i, command);
}
public void update(int i) {
commands.get(i).execute();
}
}
用 ArrayList
存儲(chǔ) Command
命令绑改,不過(guò)我們需要指定序號(hào),方便以后我們使用兄一。
下面開(kāi)始進(jìn)行測(cè)試
public class Client {
public static void main(String[] args) {
Font font = new Font();
Background background = new Background();
NormalFontCommand normalFontCommand = new NormalFontCommand(font);
LargeFontCommand largeFontCommand = new LargeFontCommand(font);
DefaultBackground defaultBackground = new DefaultBackground(background);
CustomBackground customBackground = new CustomBackground(background);
Invoker invoker = new Invoker();
invoker.setCommand(0, normalFontCommand);
invoker.setCommand(1, largeFontCommand);
invoker.setCommand(2, defaultBackground);
invoker.setCommand(3, customBackground);
invoker.update(3);
System.out.println(background.getBgColor());
}
}
我們首先把所有的命令添加到了 Invoker
, 然后直接調(diào)用 update()
方法就可以了兴革。
這么做有什么好處呢?看的出來(lái)励烦,可以將很多命令放進(jìn) Invoker
芝发, 它并不知道功能是如何實(shí)現(xiàn)的,它就像一個(gè)中介骂束, Client
請(qǐng)求一個(gè)功能耳璧,它就將這個(gè)請(qǐng)求轉(zhuǎn)給 Command
去實(shí)現(xiàn)。這種模式有很多的用途展箱,比如說(shuō)多功能遙控器旨枯,日志打印等。
還有一點(diǎn)不得不說(shuō)的混驰,我們可以使用宏命令攀隔,什么是宏命令呢?就是寫一個(gè) Command
账胧,這個(gè) Command
可以實(shí)現(xiàn)多個(gè)功能竞慢。比如說(shuō)我們可以同時(shí)修改背景和顏色。
如果有書寫錯(cuò)誤治泥,歡迎指正筹煮。