《java设计模式》之观察者设计模式

观察者设计模式:

  • 观察者设计模式解决的问题时当一个对象发生指定的动作时,要通过另外一个对象做出相应的处理。(类似事件监听)

需求

编写一个气象站、一个工人两个类,当气象站更新天气 的时候,要通知人做出相应的处理。

不用设计模式的解决思路:

(1)编写气象站类


public class WeatherStation {

    String[] weathers={"晴天","雾霾", "刮风","冰雹","下雪"};
    //当前天气
    String weather ;


    //开始工作
        public void startWork()throws Exception {
            Random random = new Random();

            while(true){
                updateWeather();//每1-5秒更新一次天气   1000~1500
                int  s = random.nextInt(501)+1000;
                Thread.sleep(s);
            }


        }



    //更新天气的方法
    public void updateWeather(){
        Random random=new Random();//随机抓天气
        int index=random.nextInt(weathers.length);//随机产生一个索引值
        weather = weathers[index];
        System.out.println("当前的天气是: " + weather);
    }
}

(2)编写工人类


public class Emp {
    String name;

    public Emp(String name) {
        this.name = name;
    }


    //人是要根据天气做出相应的处理的。  "晴天","雾霾","刮风","冰雹","下雪"
    public void notifyWeather(String weather){
        if("晴天".equals(weather)){
            System.out.println(name+"高高兴兴的去上班!!");
        }else if("雾霾".equals(weather)){
            System.out.println(name+"戴着消毒面具去上班!");
        }else if("刮风".equals(weather)){
            System.out.println(name+"拖着大石头过来上班!");
        }else if("冰雹".equals(weather)){
            System.out.println(name+"戴着头盔过来上班!");
        }else if("下雪".equals(weather)){
            System.out.println(name+"戴着被子过来上班!");
        }


    }


}

(2)编写主类运行

public class WeatherMain {
    //气象站在不断的更新的天气
    public static void main(String[] args) throws Exception {
        WeatherStation station=new WeatherStation();
        station.startWork();

        //工人
        Emp e=new Emp("小明");
        Random random=new Random();

        while(true){
            e.notifyWeather(station.weather);
            int s=random.nextInt(501)+1000;
            Thread.sleep(s);
        }

    }
}

运行后的问题1:

这里写图片描述
随机数产生不一致,导致运行结果出现问题。
气象站更新了多次天气,然后人才做一次的处理。

解决思路:

气象站主动通知人的,能否在气象站类维护一个工人,在气象站创建的时候传入这个人,气象站更新方法的时候 ,这个人更新天气?

代码如下
WeatherStation类:

package qqq;

import java.util.Random;

public class WeatherStation {

    String[] weathers={"晴天","雾霾", "刮风","冰雹","下雪"};
    //当前天气
    String weather ;

    //人
    Emp e;
    public WeatherStation(Emp e){
        this.e=e;
    }

    //开始工作
        public void startWork()throws Exception {
            Random random = new Random();
            new Thread(){
                public void run() {
                    while(true){
                        updateWeather();//每1-5秒更新一次天气   1000~1500
                        e.notifyWeather(weather);
                        int  s = random.nextInt(501)+1000;
                        try {
                            Thread.sleep(s);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
            }.start();


        }



    //更新天气的方法
    public void updateWeather(){
        Random random=new Random();//随机抓天气
        int index=random.nextInt(weathers.length);//随机产生一个索引值
        weather = weathers[index];
        System.out.println("当前的天气是: " + weather);
    }
}

WeatherMain:


public class WeatherMain {
    //气象站在不断的更新的天气
    public static void main(String[] args) throws Exception {
        //工人
        Emp e=new Emp("小明");
        Random random=new Random();
        WeatherStation station=new WeatherStation(e);
        station.startWork();

    }
}

运行后的问题2:

目前气象站只能通知一个工人而已。如果还有其他人怎么办?

解决思路:

能否把小明放入集合中,用集合来存储一堆人,这样解决?

重新修改WeatherStation代码:


public class WeatherStation {

    String[] weathers={"晴天","雾霾", "刮风","冰雹","下雪"};
    //当前天气
    String weather ;

    //工人集合
    ArrayList<Emp>list=new ArrayList<Emp>();

    public void addListener(Emp e){
        list.add(e);
    }

    //开始工作
        public void startWork()throws Exception {
            Random random = new Random();
            new Thread(){
                public void run() {
                    while(true){
                        updateWeather();//每1-5秒更新一次天气   1000~1500

                        //便利集合,挨个通知工人
                        for(Emp e:list){
                            e.notifyWeather(weather);
                        }

                        int  s = random.nextInt(501)+1000;
                        try {
                            Thread.sleep(s);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
            }.start();


        }



    //更新天气的方法
    public void updateWeather(){
        Random random=new Random();//随机抓天气
        int index=random.nextInt(weathers.length);//随机产生一个索引值
        weather = weathers[index];
        System.out.println("当前的天气是: " + weather);
    }
}

主类运行:


public class WeatherMain {
    //气象站在不断的更新的天气
    public static void main(String[] args) throws Exception {
        //工人
        Emp e=new Emp("小明");
        Emp e2=new Emp("如花");


        Random random=new Random();
        WeatherStation station=new WeatherStation();

        station.addListener(e);
        station.addListener(e2);



        station.startWork();

    }
}

运行后的问题3:

在现实生活中除了工人群体要关注天气,其他的群体也需要关注天气怎么办??学生群体关注天气怎么办??

解决思路:

观察者设计模式:

添加一个接口,让学生类、工人类去实现这个接口的方法,气象站类创建集合存储接口对象,气象站开始工作的时候去遍历集合,更新通知。

代码如下:

学生类:


public class Student implements Weather{

    String name;

    public Student(String name) {
        super();
        this.name = name;
    }


    public void notifyWeather(String weather){
        if("晴天".equals(weather)){
            System.out.println(name+"高高兴兴的去开学!!");
        }else if("雾霾".equals(weather)){
            System.out.println(name+"吸多两口去上学!");
        }else if("刮风".equals(weather)){
            System.out.println(name+"在家睡觉!");
        }else if("冰雹".equals(weather)){
            System.out.println(name+"在家睡觉!");
        }else if("下雪".equals(weather)){
            System.out.println(name+"等下完再去上学!");
        }


    }

}

工人类:

package cn.itcast.observer;

//人 是要根据天气做出相应的处理的。
public class Emp implements Weather{

    String name;

    public Emp(String name) {
        this.name = name;
    }


    //人是要根据天气做出相应的处理的。  "晴天","雾霾","刮风","冰雹","下雪"
    public void notifyWeather(String weather){
        if("晴天".equals(weather)){
            System.out.println(name+"高高兴兴的去上班!!");
        }else if("雾霾".equals(weather)){
            System.out.println(name+"戴着消毒面具去上班!");
        }else if("刮风".equals(weather)){
            System.out.println(name+"拖着大石头过来上班!");
        }else if("冰雹".equals(weather)){
            System.out.println(name+"戴着头盔过来上班!");
        }else if("下雪".equals(weather)){
            System.out.println(name+"戴着被子过来上班!");
        }


    }

}

气象站类:


//气象站
public class WeatherStation {

    String[] weathers = {"晴天","雾霾","刮风","冰雹","下雪"};

    //当前天气
    String  weather ;

    //该集合中存储的都是需要收听天气预报的人
    ArrayList<Weather> list = new ArrayList<Weather>();  //程序设计讲究低耦合---->尽量不要让一个类过分依赖于另外一个类。



    public void addListener(Weather e){
        list.add(e);
    }


    //开始工作
    public void startWork() {
        final Random random = new Random();

        new Thread(){   
            @Override
            public void run() {
                while(true){ 
                    updateWeather(); // 每1~1.5秒更新一次天气  1000~1500
                    for(Weather e : list){
                        e.notifyWeather(weather);
                    }

                    int  s = random.nextInt(501)+1000; //  500
                    try {
                        Thread.sleep(s);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }               
            }

        }.start();

    }



    //更新天气的 方法
    public void updateWeather(){
        Random random = new Random();
        int index = random.nextInt(weathers.length);
        weather = weathers[index];
        System.out.println("当前的天气是: " + weather);
    }

}

主类运行:


public class WeatherMain {

    public static void main(String[] args) throws Exception {
        //工人
        Emp e = new Emp("小明");
        Emp e2 = new Emp("如花");

        //学生
        Student s1 = new Student("狗娃");
        Student s2 = new Student("狗剩");


        WeatherStation station = new WeatherStation();
        station.addListener(e);
        station.addListener(e2);
        station.addListener(s1);
        station.addListener(s2);



        station.startWork();


    }

}

观察者设计模式的步骤总结:

1. 当前目前对象发生指定的动作是,要通知另外一个对象做出相应的处理,这时候应该把对方的相应处理方法定义在接口上。

2. 在当前对象维护接口的引用,当当前对象发生指定的动作这时候即可调用接口中的方法了。

使用观察者模式解决问题从而降低程序耦合度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值