java设计模式之观察者模式

观察者模式就是建立一种对象之间的一对多的关系,当一个对象发生改变时,自动通知依赖与它的对象并且自动更新。

这一模式的关键对象是目标对象(Subject)和观察者(Observer),一个目标可以有任意多个的观察者,当目标的状态改变时会通知它的所有观察者,观察者同步目标对象的状态信息。

思想:

Subject 接口:
public addObserver(Observer o);
public removeObserver(Observer o);public void inform();

Observer 接口:

public void updateInfo();

举例说明:

Subject是老师,Student是观察者,老师的电话号码如果变了,所有学生的电话簿里的老师信息都要更新。

代码实现:

public interface Subject {
    public void addObserver(Student s);
    public void removeObserver(Student s);
    public void inform();
}
public interface Observer {
    public void updateInfo();
}
import java.util.Vector;

public class Teacher implements Subject {
    private String name;
    private String phone;
    private Vector<Student> students;
    public Teacher(String name,String phone){
        this.name=name;
        this.phone=phone;
        this.students=new Vector<Student>();
    }
    public Teacher(String name,String phone,Vector<Student> students){
        this.name=name;
        this.phone=phone;
        this.students=students;
    }
    @Override
    public void addObserver(Student s) {
        // TODO Auto-generated method stub
            this.students.add(s);
    }

    @Override
    public void removeObserver(Student s) {
        // TODO Auto-generated method stub
            this.students.remove(s);
    }

    @Override
    public void inform() {
        // TODO Auto-generated method stub
        int size=this.students.size();
        for(int i=0;i<size;i++){
            this.students.get(i).updateInfo();
        }
    }
    public void setPhone(String phone){
        this.phone=phone;
        this.inform();
    }
    public String getPhone(){
        return this.phone;
    }
    public String getName(){
        return this.name;
    }
}
public class Student implements Observer {

    private String name;
    private String phone;
    private Teacher teacher;
    public Student(String name,Teacher t){
        this.name=name;
        this.teacher=t;
        this.phone=teacher.getPhone();
    }
    @Override
    public void updateInfo() {
        // TODO Auto-generated method stub
        this.phone=teacher.getPhone();
    }

    public void show(){
        System.out.println("My name is "+this.name+" and my teacher "+teacher.getName()+" phone number is "+this.phone);
    }
}
import java.util.Vector;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Vector<Student> students=new Vector<Student>();
        Teacher t=new Teacher("cris","1668");
        for(int i=0;i<6;i++){
            Student st=new Student("nannan"+i,t);
            students.add(st);
            t.addObserver(st);
        }
        for(int i=0;i<6;i++){
            students.get(i).show();
        }
        t.setPhone("1888");
        for(int i=0;i<6;i++){
            students.get(i).show();
        }
    }

}

测试结果:

My name is nannan0 and my teacher cris phone number is 1668
My name is nannan1 and my teacher cris phone number is 1668
My name is nannan2 and my teacher cris phone number is 1668
My name is nannan3 and my teacher cris phone number is 1668
My name is nannan4 and my teacher cris phone number is 1668
My name is nannan5 and my teacher cris phone number is 1668
My name is nannan0 and my teacher cris phone number is 1888
My name is nannan1 and my teacher cris phone number is 1888
My name is nannan2 and my teacher cris phone number is 1888
My name is nannan3 and my teacher cris phone number is 1888
My name is nannan4 and my teacher cris phone number is 1888
My name is nannan5 and my teacher cris phone number is 1888

说明老师修的状态改变后,学生也随之改变了。

但是上面的代码有个地方并不合适,就是在老师的类中:

Vector<Student> students=new Vector<Student>();这一句如果改成:

Vector<Observer> students=new Vector<Observer>();会更好一些,这样就不会只是限制在Student对象,而是继承自Observer的子类都可以,但是需要一些强制转换。

作如下修改:

public interface Subject {
    public void addObserver(Observer s);
    public void removeObserver(Observer s);
    public void inform();
}
import java.util.Vector;

public class Teacher implements Subject {
    private String name;
    private String phone;
    private Vector<Observer> students;
    public Teacher(String name,String phone){
        this.name=name;
        this.phone=phone;
        this.students=new Vector<Observer>();
    }
    public Teacher(String name,String phone,Vector<Observer> students){
        this.name=name;
        this.phone=phone;
        this.students=students;
    }
    @Override
    public void addObserver(Observer s) {
        // TODO Auto-generated method stub
            this.students.add(s);
    }

    @Override
    public void removeObserver(Observer s) {
        // TODO Auto-generated method stub
            this.students.remove(s);
    }

    @Override
    public void inform() {
        // TODO Auto-generated method stub
        int size=this.students.size();
        for(int i=0;i<size;i++){
            this.students.get(i).updateInfo();
        }
    }
    public void setPhone(String phone){
        this.phone=phone;
        this.inform();
    }
    public String getPhone(){
        return this.phone;
    }
    public String getName(){
        return this.name;
    }
}
import java.util.Vector;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Vector<Observer> students=new Vector<Observer>();
        Teacher t=new Teacher("cris","1668");
        for(int i=0;i<6;i++){
            Student st=new Student("nannan"+i,t);
            students.add(st);
            t.addObserver(st);
        }
        for(int i=0;i<6;i++){
            ((Student)students.get(i)).show();
        }
        t.setPhone("1888");
        for(int i=0;i<6;i++){
            ((Student)students.get(i)).show();
        }
    }
}

这就是子类继承父类或者接口,就可以用子类实例化后强制转化父类,但是强制转化后只有父类的功能,子类多余的功能不能用。

posted @ 2013-09-10 19:16  楠楠IT  阅读(311)  评论(0编辑  收藏  举报