[疯狂Java]监听器的实现:内部(闭包)、反射、外部

来源:互联网 发布:pdf修改软件绿色版 编辑:程序博客网 时间:2024/05/22 02:09

1. 用内部类和闭包实现监听器:

    1) 之前讲的所有形式都是内部类实现监听器,即在类内部定义一个监听器;

    2) 但最常用的还是闭包了,即匿名内部类和Lambda表达式:

         i. 因为监听器通常都是临时使用的代码,往往不会在其它地方被复用;

         ii. 即使要复用肯定会被抽象到业务逻辑层面单独编写;

         iii. 因此通常为了方便会用匿名内部类或者Lambda表达式来实现监听器;

     3) 匿名内部类示例:

Frame f = new Frame("Test");f.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {// TODO Auto-generated method stub// super.windowClosing(e);System.exit(0);}});
!!由于WindowAdapter不只有一个方法(7个),因此不是函数式接口,不能使用Lambda表达式;

    4) Lambda表达式:只适用于函数是接口,注意!函数式监听器接口(ActionListener等)没有对应的适配器,因为只有一个方法,没必要提供适配器

Button btn = new Button("button");btn.addActionListener(e -> System.out.println(e.getActionCommand()));

2. 反射:

    1) 反射一词来自MFC,即组件自己监听自己的意思,这种组件就是智能组件,这种反射就叫做组件反射;

    2) 当然在Java中就是让类自己来监听自己的组件,这就叫类反射,当然MFC式的组件反射也可以实现;

    3) 反射的示例:类反射和组件反射

public class AwtTest extends WindowAdapter { // 类自己监听自己的组件Frame f = new Frame("WindowAdapter Test");class MyButton extends Button implements ActionListener { // 组件自己监听自己public MyButton(String label) throws HeadlessException {super(label);// TODO Auto-generated constructor stubthis.addActionListener(this); // 组件自反射}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubSystem.out.println("Button pushed!");}}@Overridepublic void windowClosing(WindowEvent e) {// TODO Auto-generated method stubSystem.exit(0);}public void init() {f.addWindowListener(this); // 类自反射f.add(new MyButton("button"));f.pack();f.setVisible(true);}public static void main(String[] args) {new AwtTest().init();}}
!像这样的按钮只要new出来随便用就行了,它产生的事件都由它自己来处理(自定义按钮);

!!注意this的应用是实现反射的关键;

    4) 反射的缺点:

         i. 通常组件、GUI类(用于显示界面的类,上面的类就是GUI类,PS:其实组件也是GUI类,用于显示组件本身)就只负责显示界面;

         ii. 监听、处理事件应该放到另一个模块来处理,因为这符合MVC设计思想;

         iii. 因此反射的缺点就是程序结构混乱,模块耦合度高;


3. 外部:

    1) 将监听器单独定义成外部类,然后GUI界面调用它;

    2) 最大的缺点:

         i. 监听器通常属于特定的GUI界面,定义在外部降低了程序的内聚性;

         ii. 外部类不能自由访问GUI界面类中的数据(组件),编程不简洁;

    3) 示例:监听邮件发送按钮的监听器定义在外部

         i. 监听器:

public class MailerListener implements ActionListener {private TextField mailAdress;public MailerListener() {}public MailerListener(TextField mailAdress) {this.mailAdress = mailAdress;}public TextField getMailAdress() {return mailAdress;}public void setMailAdress(TextField mailAdress) {this.mailAdress = mailAdress;}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubSystem.out.println("sending mail to '" + mailAdress.getText() + ".'\n");}}
         ii. GUI:

public class AwtTest extends WindowAdapter { // 类自己监听自己的组件@Overridepublic void windowClosing(WindowEvent e) {// TODO Auto-generated method stub// super.windowClosing(e);System.exit(0);}public void init() {Frame f = new Frame("Sending Mail Test");TextField tf = new TextField(40);Button btn = new Button("send");f.addWindowListener(this);btn.addActionListener(new MailerListener(tf));f.add(tf);f.add(btn, BorderLayout.SOUTH);f.pack();f.setVisible(true);}public static void main(String[] args) {new AwtTest().init();}}
!!可以看到监听器和GUI之间存在数据的共享,这加大了模块之间的耦合度,这无疑是对程序健壮性的一种危害!!要慎重使用;



0 0
原创粉丝点击