观察者设计模式

来源:互联网 发布:锤子科技 成都 知乎 编辑:程序博客网 时间:2024/06/05 02:19

何为设计模式

在我看来,设计模式就是在重复做了大量类似的工作之后,进行的规律总结,你也可以把它理解为套路,就比如在计算99*5的时候,可能一开始你会一步一步慢慢计算得出结果,但是当你的计算能力提升到一定水平之后,你就会发现,直接(100-1)* 5,就会方便很多。设计模式也可以这样理解,当你的代码量达到一定数量的时候,你就可以总结出一些方便的开发技巧,这些技巧是可以显著减少代码的复杂程度,提高代码的复用率的,类似的好处有很多,我自己也在慢慢体会中。

观察者设计模式

在观察者设计模式中,最有代表性的例子就是气象站的例子了。
需求一:
气象站在一定时间内,更新天气信息,然后工人做出相应的措施
Emp类:用于表示工人对象
WeatherStation:用于表示气象站
WeatherMain:程序入口
代码如下:
WeatherMain类

package com.lingadobe.observe;public class WeatherMain {    public static void main(String[] args){        Emp e1=new Emp("张三");        Emp e2=new Emp("李四");        WeatherStation station =new WeatherStation();        station.addListener(e1);        station.addListener(e2);        station.startWork();    }}

WeatherStation类

package com.lingadobe.observe;import java.util.ArrayList;import java.util.Random;public class WeatherStation {    String [] weathers={"晴天","雨天","下雪"};    String weather;    ArrayList<Emp> list=new ArrayList<Emp>();    public WeatherStation(){    }    public void addListener(Emp e){        list.add(e);    }    public void startWork(){        new Thread(){            public void run(){                while(true){                    updateWeather();                    for(Emp e:list){                        e.changeByWeather(weather);                    }                    int s=100;                    try{                        Thread.sleep(s);                    }catch(InterruptedException e){                        e.printStackTrace();                    }                }            }        }.start();    }    protected void updateWeather() {        // TODO Auto-generated method stub        Random random = new Random();        int index=random.nextInt(weathers.length);        weather=weathers[index];        System.out.println("当前天气为:"+weather);    }}

Emp类

package com.lingadobe.observe;public class Emp {    String name;    public Emp(String name){        this.name=name;    }    public void changeByWeather(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+"不上班");        }    }}

运行结果如下:

当前天气为:雨天
张三撑伞上班
李四撑伞上班
当前天气为:雨天
张三撑伞上班
李四撑伞上班
当前天气为:晴天
张三正常上班
李四正常上班
当前天气为:雨天
张三撑伞上班
李四撑伞上班
当前天气为:下雪
张三不上班
李四不上班

这里就是在WeatherStation类中维护一个ArrayList集合,用来存放需要收听天气广播的人群,然后每隔1秒,更新天气,调用相应的方法来做出改变。

需求二:如果添加学生,老师,医生,….群体,都需要来实现收听广播的功能,又该如何做出改变呢?

之前在学习多态的时候,就有这个类似的需求,比如所有的动物都有叫的行为,所以在动物接口中定义一个叫的方法,然后具体到某一个动物叫的行为时,实现父类动物类的叫的方法,然后父类对象创建不同的引用,指向子类对象,比如:Animal ani=new Dog();
Animal ani=new Cat(); 等等,这样做的好处是:提高了代码的复用性

类似的,在这里我们也可以创建不同的群体对象,然后向上抽取出一个接口,这个接口就是专门用于收听天气广播的,然后子类覆盖该方法,不同的子类具有不同的举措,来响应天气的改变。这是多态的一个特点。
代码如下:

Emp类

package com.lingadobe.observe;public class Emp implements Weather{    String name;    public Emp(String name){        this.name=name;    }    public void changeByWeather(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+"不上班");        }    }}

WeatherStation类

package com.lingadobe.observe;import java.util.ArrayList;import java.util.Random;public class WeatherStation {    String [] weathers={"晴天","雨天","下雪"};    String weather;    ArrayList<Weather> list=new ArrayList<Weather>();    public WeatherStation(){    }    public void addListener(Weather e){        list.add(e);    }    public void startWork(){        new Thread(){            public void run(){                while(true){                    updateWeather();                    for(Weather e:list){                        e.changeByWeather(weather);                    }                    int s=1000;                    try{                        Thread.sleep(s);                    }catch(InterruptedException e){                        e.printStackTrace();                    }                }            }        }.start();    }    protected void updateWeather() {        // TODO Auto-generated method stub        Random random = new Random();        int index=random.nextInt(weathers.length);        weather=weathers[index];        System.out.println("当前天气为:"+weather);    }}

WeatherMain类

package com.lingadobe.observe;public class WeatherMain {    public static void main(String[] args){        Emp e1=new Emp("张三");        Emp e2=new Emp("李四");        Student s1=new Student("小明");        Student s2=new Student("小丽");        WeatherStation station =new WeatherStation();        station.addListener(e1);        station.addListener(e2);        station.addListener(s1);        station.addListener(s2);        station.startWork();    }}

Student类

package com.lingadobe.observe;public class Student implements Weather{    String name;    public Student(String name){        this.name=name;    }    public void changeByWeather(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+"不上学");        }    }}

Weather类

package com.lingadobe.observe;public interface Weather {    public void changeByWeather(String weather);}

可以发现,使用观察者设计模式,其实就是充分利用多态的原理,来实现不同的子类做出不同响应的。

0 0
原创粉丝点击