美文网首页
行为型模式:20-观察者模式

行为型模式:20-观察者模式

作者: 综合楼 | 来源:发表于2021-06-20 19:00 被阅读0次

    观察者模式(Observer Pattern):定义对象之间的一种一对多依赖关系,
    使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
    观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器
    (Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

    image.png

    在观察者模式结构图中包含如下几个角色:

    ● Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集
    合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察
    者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。

    ● ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数
    据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义
    的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。

    ● Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接
    口声明了更新数据的方法update(),因此又称为抽象观察者。

    ● ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它
    存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观
    察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自
    己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。

    代码示例:

    import java.util.ArrayList;
    
    public abstract class MySubject {
        protected ArrayList observers = new ArrayList();
    
        //注册方法
        public void attach(MyObserver observer) {
            observers.add(observer);
        }
    
        //注销方法
        public void detach(MyObserver observer) {
            observers.remove(observer);
        }
    
        public abstract void cry(); //抽象通知方法
    }
    
    public interface MyObserver {
        void response();  //抽象响应方法
    }
    ------------------------------------------------------
    public class Cat extends MySubject {
        public void cry() {
            System.out.println("猫叫!");
            System.out.println("----------------------------");
    
            for (Object obs : observers) {
                ((MyObserver) obs).response();
            }
    
        }
    }
    ------------------------------------------------------
    public class Dog implements MyObserver {
        public void response() {
            System.out.println("狗跟着叫!");
        }
    }
    ------------------------------------------------------
    public class Mouse implements MyObserver {
        public void response() {
            System.out.println("老鼠努力逃跑!");
        }
    }
    ------------------------------------------------------
    public class Pig implements MyObserver {
        public void response() {
            System.out.println("猪没有反应!");
        }
    }
    
    public class Client {
        public static void main(String a[]) {
            MySubject subject = new Cat();
    
            MyObserver obs1, obs2, obs3;
            obs1 = new Mouse()  ;
            obs2 = new Mouse();
            obs3 = new Dog();
    
            subject.attach(obs1);
            subject.attach(obs2);
            subject.attach(obs3);
    
            MyObserver obs4;
            obs4 = new Pig();
            subject.attach(obs4);
    
            subject.cry();
        }
    }
    
    image.png

    JDK对观察者模式的支持

    image.png

    自定义登录组件

    image.png
    import java.util.EventObject;
    
    public class LoginEvent extends EventObject {
        private String userName;
        private String password;
    
        public LoginEvent(Object source, String userName, String password) {
            super(source);
            this.userName = userName;
            this.password = password;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserName() {
            return this.userName;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getPassword() {
            return this.password;
        }
    }
    
    //Concrete Subject
    public class LoginBean extends JPanel implements ActionListener {
        private JLabel labUserName, labPassword;
        private JTextField txtUserName;
        private JPasswordField txtPassword;
        private JButton btnLogin, btnClear;
    
        private LoginEventListener lel;  //Abstract Observer
    
        private LoginEvent le;
    
        public LoginBean() {
            this.setLayout(new GridLayout(3, 2));
            labUserName = new JLabel("User Name:");
            add(labUserName);
    
            txtUserName = new JTextField(20);
            add(txtUserName);
    
            labPassword = new JLabel("Password:");
            add(labPassword);
    
            txtPassword = new JPasswordField(20);
            add(txtPassword);
    
            btnLogin = new JButton("Login");
            add(btnLogin);
    
            btnClear = new JButton("Clear");
            add(btnClear);
    
            btnClear.addActionListener(this);
            btnLogin.addActionListener(this);//As a concrete observer for another subject,ActionListener as the abstract observer.
        }
    
        //Add an observer.
        public void addLoginEventListener(LoginEventListener lel) {
            this.lel = lel;
        }
    
        //private or protected as the notify method
        private void fireLoginEvent(Object object, String userName, String password) {
            le = new LoginEvent(btnLogin, userName, password);
            lel.validateLogin(le);
        }
    
        public void actionPerformed(ActionEvent event) {
            if (btnLogin == event.getSource()) {
                String userName = this.txtUserName.getText();
                String password = this.txtPassword.getText();
    
                fireLoginEvent(btnLogin, userName, password);
            }
            if (btnClear == event.getSource()) {
                this.txtUserName.setText("");
                this.txtPassword.setText("");
            }
        }
    }
    
    //Abstract Observer
    public interface LoginEventListener extends EventListener {
        public void validateLogin(LoginEvent event);
    }
    ------------------------------------------------------------------------------------------------------
    //Concrete Observer
    public class LoginValidatorA extends JFrame implements LoginEventListener {
        private JPanel p;
        private LoginBean lb;
        private JLabel lblLogo;
    
        public LoginValidatorA() {
            super("Bank of China");
            p = new JPanel();
            this.getContentPane().add(p);
            lb = new LoginBean();
            lb.addLoginEventListener(this);
    
            Font f = new Font("Times New Roman", Font.BOLD, 30);
            lblLogo = new JLabel("Bank of China");
            lblLogo.setFont(f);
            lblLogo.setForeground(Color.red);
    
            p.setLayout(new GridLayout(2, 1));
            p.add(lblLogo);
            p.add(lb);
            p.setBackground(Color.pink);
            this.setSize(600, 200);
            this.setVisible(true);
        }
    
        public void validateLogin(LoginEvent event) {
            String userName = event.getUserName();
            String password = event.getPassword();
    
            if (0 == userName.trim().length() || 0 == password.trim().length()) {
                JOptionPane.showMessageDialog(this, new String("Username or Password is empty!"), "alert", JOptionPane.ERROR_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(this, new String("Valid Login Info!"), "alert", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    
        public static void main(String args[]) {
            new LoginValidatorA().setVisible(true);
        }
    }
    ------------------------------------------------------------------------------------------------------
    public class LoginValidatorB extends JFrame implements LoginEventListener {
        private JPanel p;
        private LoginBean lb;
        private JLabel lblLogo;
    
        public LoginValidatorB() {
            super("China Mobile");
            p = new JPanel();
            this.getContentPane().add(p);
            lb = new LoginBean();
            lb.addLoginEventListener(this);
    
            Font f = new Font("Times New Roman", Font.BOLD, 30);
            lblLogo = new JLabel("China Mobile");
            lblLogo.setFont(f);
            lblLogo.setForeground(Color.blue);
    
            p.setLayout(new GridLayout(2, 1));
            p.add(lblLogo);
            p.add(lb);
            p.setBackground(new Color(163, 185, 255));
            this.setSize(600, 200);
            this.setVisible(true);
        }
    
        public void validateLogin(LoginEvent event) {
            String userName = event.getUserName();
            String password = event.getPassword();
    
            if (userName.equals(password)) {
                JOptionPane.showMessageDialog(this, new String("Username must be different from password!"), "alert", JOptionPane.ERROR_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(this, new String("Rigth details!"), "alert", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    
        public static void main(String args[]) {
            new LoginValidatorB().setVisible(true);
        }
    }
    

    相关文章

      网友评论

          本文标题:行为型模式:20-观察者模式

          本文链接:https://www.haomeiwen.com/subject/ccfgeltx.html