哪个更适合类中的多个操作? actionPerformed() 中的匿名内部类或 if 语句?

Posted

技术标签:

【中文标题】哪个更适合类中的多个操作? actionPerformed() 中的匿名内部类或 if 语句?【英文标题】:Which is better for multiple actions in a class? Anonymous inner classes or if statements in actionPerformed()? 【发布时间】:2018-03-26 01:34:30 【问题描述】:

我正致力于在 java JFrame 中制作菜单。我见过两种对同一班级的不同事件做出不同反应的方法。一种是使用几年前的这个答案中描述的匿名内部类: https://***.com/a/10472395/5960074

public static void createMenuBar()

    //Main Menu Items

    menubar.add(fileMenu);
    MainWindow.window.setJMenuBar(menubar);

    //Sub menu items
    saveItem = new JMenuItem("Save");
    loadItem = new JMenuItem("Load");

    //Add to the "File" menu item
    fileMenu.add(saveItem);
    fileMenu.add(loadItem);

    //Anonymous Inner classes for actionListeners


    //Action event for saving
    saveItem.addActionListener(new ActionListener() //adding the listener
        @Override
        public void actionPerformed(ActionEvent e) //creating the specific action for save
            System.out.println("You tried to save.");
        
    );


在我的代码中,它看起来像这样并且可以正常工作(因为此时它将“您尝试保存。”打印到控制台)。

我见过其他人在类中实现 ActionListener,然后在方法 actionPerformed() 中使用 if 语句来跟踪事件的来源。所以只有一个事件,但代码会根据触发它的原因发生变化。

第一种方法看起来很混乱,第二种方法更容易阅读。是否有理由使用第一种方法而不是第二种方法?

谢谢。

【问题讨论】:

答案是,两者都不是。这将归结为需求。 Action API 是另一种允许生成可重用代码块的方法 你能想出为什么其中一个会更好的原因吗?我正在尝试使用此类设置一个菜单栏,以允许用户保存和加载数据。 什么是“更好”是征求意见。应用不同的风格,体验它们如何影响可读性以及何时从一种风格切换到另一种风格。 一切都与上下文有关 - 我个人更喜欢 Action 或匿名类,它们都提供了一个专注的控制器,不依赖于假设或额外的配置,这些配置可能会改变并且难以维护或理解. Action 提供了一个自包含/可配置的工作单元,如果你聪明的话,它可以用来生成抽象层。想想保存和打开——唯一真正的区别是一个写入和一个读取,但除此之外他们想要执行相同的基本操作,提示用户输入文件 【参考方案1】:

将Action 类与非匿名类一起使用(尽管它们可以是静态内部类)。它为您提供了很好的封装,使代码具有可读性,并且在许多方面都比使用 ActionListener 更好。

【讨论】:

【参考方案2】:

首先,避免使用static,你真的(真的)不需要它,它会促进糟糕的代码设计。

假设您使用 Java 8,因此可以使用 lambda:

public void createMenuBar() 
   ...
   saveItem.addActionListener(this::save);
   loadItem.addActionListener(this::load);
 

private save(ActionEvent e)  
    .... 


private load(ActionEvent e)  
   .... 

如果您不能使用 lambda,则使用内部类比实现接口和使用 if 语句更好。

 public class MyGui 
     private class SaveAction implements ActionListener 
        @Override
        public void actionPerformed(ActionEvent e) 
           ....
        
    

     private class LoadAction implements ActionListener 
        @Override
        public void actionPerformed(ActionEvent e) 
           ....
        
    

 public void createMenuBar() 
   ...
   saveItem.addActionListener(new SaveAction());
   loadItem.addActionListener(new LoadAction());
  

【讨论】:

感谢您的回复。我曾经在 main 方法中调用此方法,但现在我没有,而且我忘记了摆脱静态。具体来说,在代码中使用静态有什么不好? 我认为我们没有足够的空间来解释static 的所有问题。但是,在main 函数中写入诸如new MyGui().show() 之类的东西,然后在show() 方法中创建并显示您的gui。如果您遇到问题,可能会出现一个新的 SO 问题。 @admiralmattbar 静态被认为是不好的做法有很多原因 - 对全局变量进行一些研究。一个问题是它们不允许写控制,所以程序的其他部分可能会更改引用,突然间你会出现不可预知的行为。它们还结合了您的核心并降低了可重用性并限制了扩展——就像某些点

以上是关于哪个更适合类中的多个操作? actionPerformed() 中的匿名内部类或 if 语句?的主要内容,如果未能解决你的问题,请参考以下文章

DOM API 或 innerHTML 哪个更适合 DOM 操作?

哪个更适合 UDF:CFC 与 CFM

哪个关系模型更适合这个例子?

哪个更适合用于序列化对象? JsonSerializer 或 JsonConvert

Kali Linux和Parrot OS,哪个更适合安全

IBM MObile First 中的推送通知:哪个更适合发送推送通知、MobileFirst Operations Console 或通过 REST API