`

体验模式的乐趣(一)—— Command模式

阅读更多

        模式是什么?说实在的,对于模式,我了解得很少。但是,我知道,模式是用来解决软件设计问题的,是用来增加软件设计的灵活性和可维护性的,总之,它应该是程序员经过大量开发工作之后,对于解决问题的经验总结;模式不是用来生搬硬套的,也不是拿来故弄玄虚的,它是用来解决问题,从而让我们更加享受编码的乐趣。我无意直接去讲解什么模式,因为我还没有那样的实力,我能够讲的就只有模式给我带来的顿悟了。咦,怎么文不对题了呢?呵呵,有了顿悟,难道还不是莫大的乐趣吗?闲话少说,言归正传。
        首先,让我们先来看一段代码:

public class MainFrame extends JFrame {
  JPanel panel;

  
public MainFrame() {
  panel 
= new JPanel();
  panel.setLayout(
new FlowLayout());
  JButton blueButton 
= new JButton("Blue");
  blueButton.addActionListener(
new BlueColorActionListener());
  JButton redButton 
= new JButton("Red");
  redButton.addActionListener(
new RedColorActionListener());
  panel.add(blueButton);
  panel.add(redButton);
  getContentPane().add(panel);
  setSize(
300100);
  setVisible(
true);
 }

 
 
class BlueColorActionListener implements ActionListener {
  
public void actionPerformed(ActionEvent event{
   panel.setBackground(Color.blue);
  }

 }

 
 
class RedColorActionListener implements ActionListener {
  
public void actionPerformed(ActionEvent event{
   panel.setBackground(Color.red);
  }

 }

 
 
public static void main(String[] args) {
  MainFrame frame 
= new MainFrame();
 }

}

        如果你有写过Java GUI的程序,一定会对以上的代码很熟悉。这段小代码实现的功能也很简单,就是通过点击按钮去改变窗口的背景颜色。大家在看这段代码的时候,有没有不爽的感觉呢?是的,就是这里了。为了使得窗口上的按钮能够响应鼠标或者是键盘的事件,我们都必须为每个按钮增加相应的ActionListener。如果每个button对应Click事件有迥异的处理,那么构建不同的ActionListener也是无可厚非的,但是,如果按下button,所做的事情很类似呢?譬如以上代码中,两个按钮的功能就很类似,一个是让背景变成红色,一个则是蓝色而已。那么,我们是不是应该将这些共同点提取出来,以减少代码的重复呢?接着就是第二个版本的程序了,使用CommonActionListener去替代原有的两个ActionListener:

class CommonActionListener implements ActionListener {
  
public void actionPerformed(ActionEvent event{
   JButton button 
= (JButton)event.getSource();
   
if (button.getText().equals("Blue"))
    panel.setBackground(Color.blue);
   
else if (button.getText().equals("Red"))
    panel.setBackground(Color.red); 
  }

}

        这样的改动之后,最明显的提高之处就是减少了一个Inner Class,让代码更加集中了,同时复杂性也转嫁到了一个class中。大家可以想象,随着button的增加,if...else的数量也随之增加,如果又出现了一个不同功能的button,增加新的ActionListener也是必不可少的。这个CommonActionListener根本就不Common。到底怎么样才能让它变成真正Common呢?好,最重要的问题终于提出来了。

        为了解决这个问题或许有不同的途径,其中的一条就是将真正的事件处理代码从ActionListener中剥离出来,同时利用强大的多态来避免条件的判断。既然要使用到多态了,那么我们就要从类型上去区分功能不同的button了,同时让它们对外具有相同的API。下面就是最终版本的程序了:
public interface Command {
    
public void execute();
}
                                                      (Command.java)
class BlueButton extends JButton implements Command {
    JPanel panel;
    
public BlueButton(String text, JPanel panel) {
        super(text);
        
this.panel = panel;    
        
this.addActionListener(new CommonActionListener());
    }

    
public void execute() {
        panel.setBackground(Color.blue);
    }

}


class RedButton extends JButton implements Command {
    JPanel panel;
    
public RedButton(String text, JPanel panel) {
        super(text);
        
this.panel = panel;    
        
this.addActionListener(new CommonActionListener());
    }

    
public void execute() {
        panel.setBackground(Color.red);
    }

}
                                                    (Button.java)
public class CommonActionListener implements ActionListener {
    
public void actionPerformed(ActionEvent event{
        Command command 
= (Command)event.getSource();
        command.execute();
    }

}
                                             (CommonActionListener.java)
public class MainFrame extends JFrame {
    
public MainFrame() {
      JPanel panel 
= new JPanel();
      panel.setLayout(
new FlowLayout());
      JButton blueButton 
= new BlueButton("Blue", panel);
      JButton redButton 
= new RedButton("Red", panel);
      panel.add(blueButton);
      panel.add(redButton);
      getContentPane().add(panel);
      setSize(
300100);
      setVisible(
true);
    }
    
    
    
public static void main(String[] args) {
      MainFrame frame 
= new MainFrame();
    }

}

                                                        (MainFrame.java)

        以上的代码正是使用Command模式,对于ActionListener而言,它只是知道调用execute方法,而这个方法对于每一个button都是适用的,就像是命令(Command)一样,而真正的处理则放到了每个特定的button中。就像一位指挥官对着士兵们喊出Action,接着士兵们就去行动了,而指挥官并不需要知道士兵们怎么去做事情,因为指挥官知道士兵们都能做好事情,这些士兵都是服从命令的(实现了Command接口)。需要说明的一点是,在这里由于两个button的功能比较类似,这样组织代码所带来的好处并不是非常突出,大家可以考虑一下,如果button的功能截然不同的情况。

分享到:
评论

相关推荐

    业务层框架 —— Command Pattern指南.mht

    业务层框架 —— Command Pattern指南.mht业务层框架 —— Command Pattern指南.mht

    iOS实例开发源码——commanda-TwitterGame-26b6290.zip

    iOS实例开发源码——commanda-TwitterGame-26b6290.zip

    设计模式作业——用命令模式java语言编写的烧烤店

    在这个“设计模式作业——用命令模式java语言编写的烧烤店”项目中,我们将探讨如何运用命令模式来构建一个模拟烧烤店的系统。命令模式是一种行为设计模式,它将请求封装为一个对象,使得我们可以参数化不同的请求、...

    command 模式的c++实现

    **命令模式(Command Pattern)详解** 命令模式是一种行为设计模式,它将请求封装为一个对象,使得你可以使用不同的请求、队列或者日志请求,也可以支持可撤销的操作。在C++中实现命令模式,可以有效地解耦调用者和...

    命令模式(Command模式)

    **命令模式(Command模式)详解** 命令模式是一种行为设计模式,它将请求封装为一个对象,使得我们可以使用不同的请求、队列或者记录请求日志,还可以支持可撤销的操作。在命令模式中,我们创建表示各种操作的类...

    RIP——COMMAND

    rip的命令,我总结的关于常见的rip的命令,很好用的亲。谢谢支持!谢谢!

    设计模式——命令模式

    同时,命令模式还支持撤销操作,只需添加一个undo()方法到Command接口,然后在ConcreteCommand中实现具体撤销逻辑。 在实际应用中,命令模式常用于GUI系统中的事件处理,例如按钮点击事件,以及在框架和库中实现...

    设计模式之Command(命令)模式

    Command模式是一种行为设计模式,它将请求封装为一个对象,使得可以使用不同的请求、队列或者日志请求,同时支持可撤销的操作。这种模式在软件工程中广泛应用于解耦请求的发送者和接收者,使系统更加灵活和易于维护...

    设计模式精解——GoF23中设计模式解析

    7. **Command模式**:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。这种模式适用于需要将请求封装成对象,以便使用不同的请求,队列请求,...

    EJB设计模式概述——讲解EJB设计模式的重要性及常用的模式

    EJB(Enterprise JavaBeans)设计模式是解决在Java EE平台中使用EJB组件遇到的问题和挑战的一种策略。这些模式旨在优化系统性能、可扩展性、可维护性,以及提高组件的重用性。在大型、复杂的项目中,尤其在团队协作...

    Command模式(Java设计模式)

    Command模式是一种行为设计模式,它将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。在Java编程中,这种模式被广泛应用于实现命令行操作、GUI事件...

    设计模式代码——c#

    14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern) 17. 解释器模式(Interpreter Pattern) 18. 中介者模式(Mediator Pattern) 19. 职责链模式(Chain of ...

    设计模式-command

    在“设计模式-command”中,我们看到这个模式的应用,通过将一个操作封装为一个对象(即命令对象),使得发送者可以无需知道接收者的具体实现,只需要知道如何发送命令即可。这种松耦合使得系统更易于维护和扩展。 ...

    设计模式之命令模式(Command Pattern)

    命令模式是一种行为设计模式,它将请求封装成独立的对象,使得可以使用不同的请求、队列请求、记录请求历史以及支持可撤销的操作。这种模式在软件工程中被广泛应用,尤其是在需要解耦请求发起者和接收者时,提高了...

    设计模式之Command模式和代码实现

    Command模式是一种行为设计模式,它的主要目的是将命令的发起者(Invoker)与命令的执行者(Receiver)解耦。在Command模式中,一个命令对象封装了特定的请求,调用者(Invoker)只需要知道如何发送命令,而无需知道...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    C++设计模式代码资源23_Command_命令模式.zip

    命令模式是一种行为设计模式,它将请求封装为一个对象,使得你可以使用不同的请求、队列或者记录请求日志,同时支持可撤销的操作。在C++编程中,命令模式是一种非常实用的设计模式,能够帮助我们实现松耦合的系统,...

    Command模式

    Command模式是一种行为设计模式,它将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。在C++中实现Command模式,我们可以遵循以下几个关键步骤和...

Global site tag (gtag.js) - Google Analytics