Java 设计模式 -- 命令模式
pbyp4943
8年前
<h3><strong>前提</strong></h3> <p>介绍这么模式之前,我们首先来看看它的类图。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/19c2b1b7930dde490962227c471b22ca.jpg"></p> <p>根据这个图我们来分析一下何为命令模式。首先就是我们的 Client 想要实现一个功能,于是它就创建了一个 Command , 为了方便调用将 Command 封装在了 Invoker 中,当我们想调用的时候, Invoker 会执行内部 Command 提供的方法, Receiver 接收到 Command 的请求,为其提供底部支持。</p> <p>多说无益,我将通过一个例子介绍命令模式。</p> <h3><strong>实例</strong></h3> <p>目前大部分的软件都支持用户自定义界面,比如说我们可以修改字体大小,背景颜色等。我们就以此为例。首先,写出两个类。</p> <pre> <code class="language-java">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; } }</code></pre> <p>以上这两个类在命令模式的类图中扮演的是 Receiver 角色,提供底层支持。</p> <pre> <code class="language-java">public interface Command { public void execute(); }</code></pre> <p>这是 Command , 修改字体大小和背景的类都继承于此。</p> <pre> <code class="language-java">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"); } }</code></pre> <p>很简单的,我们只是在类中获得一个 Font 类的引用,然后调用 setFontSize() 方法对字体的大小进行设置。</p> <p>因为背景颜色的种类特别多,如果我们针对每种颜色都编写一个类,那就太不实际了。所以我们决定用两个类去实现它,一个类表示是默认颜色,一个是类表示非默认颜色。</p> <pre> <code class="language-java">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"); } }</code></pre> <p>好了,通过以上操作,我们不仅定义好了 Command ,还定义了 Receiver 类,下面就差 Invoker 类了。</p> <pre> <code class="language-java">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(); } }</code></pre> <p>用 ArrayList 存储 Command 命令,不过我们需要指定序号,方便以后我们使用。</p> <p>下面开始进行测试</p> <pre> <code class="language-java">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()); } }</code></pre> <p>我们首先把所有的命令添加到了 Invoker , 然后直接调用 update() 方法就可以了。</p> <p>这么做有什么好处呢?看的出来,可以将很多命令放进 Invoker , 它并不知道功能是如何实现的,它就像一个中介, Client 请求一个功能,它就将这个请求转给 Command 去实现。这种模式有很多的用途,比如说多功能遥控器,日志打印等。</p> <p>还有一点不得不说的,我们可以使用宏命令,什么是宏命令呢?就是写一个 Command ,这个 Command 可以实现多个功能。比如说我们可以同时修改背景和</p> <p>来自:http://www.jianshu.com/p/3fd3166c7662</p> <p> </p>