<h3>引入:</h3>
<h5>需求:</h5>有一個(gè)氣象臺每隔1~1.5秒會更新一次天氣,那么學(xué)生應(yīng)該在其每次更新天氣的時(shí)候能夠?qū)崟r(shí)的接收到最新天氣且做出響應(yīng)
學(xué)生類不變
public class Student implements Weather{
private String name;
public Student(String name){
this.name = name;
}
@Override
public void observerWeather(String curWeather) {
//晴天","暴雨","霜凍","臺風(fēng)","冰雹","霧霾"};
switch(curWeather){
case "晴天":
System.out.println(this.name+":天氣這么好,應(yīng)該去走走");
break;
case "暴雨":
System.out.println(this.name+":這么大的雨就別去上課了");
break;
case "霜凍":
System.out.println(this.name+":好冷啊,還是在宿舍睡覺吧");
break;
case "臺風(fēng)":
System.out.println(this.name+":臺風(fēng)來啦,好可怕,還上課干嘛");
break;
case "冰雹":
System.out.println(this.name+":你想被砸死嗎?反正我是不會去上課的");
break;
case "霧霾":
System.out.println(this.name+":麻煩你幫我跟老師請個(gè)假,我中毒不輕");
break;
}
}
}
實(shí)現(xiàn)一:
class WeatherStation{
String []weathers={"晴天","暴雨","霜凍","臺風(fēng)","冰雹","霧霾"};
String curWeather;
Random random = new Random();
public void startWork(){
new Thread(){
@Override
public void run() { //用一個(gè)逆名內(nèi)部類來開啟一個(gè)新線程
while(true){
updateWeather();
//每 隔1~1.5秒更新一次天氣
int millis = random.nextInt(501)+1000;
try {
Thread.sleep(millis);//新線程睡眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
private void updateWeather(){
int sel = random.nextInt(6);
curWeather = weathers[sel];
System.out.println("氣象臺:今天天氣"+curWeather);
}
}
class Demo01{
public static void main(String args[]){
WeatherStation ws = new WeatherStation ();
ws.startWork();
Student stu = new Student("丁昌江");
Random random = new Random();
while(true){
int millis = random.nextInt(501)+1000;
try {
Thread.sleep(millis);
stu.observerWeather(ws.curWeather);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
結(jié)果:并沒有實(shí)現(xiàn)天氣更新一次,學(xué)生就會作出一次反應(yīng),因?yàn)閮蓚€(gè)線程,兩個(gè)隨機(jī)的時(shí)間都可能造成偏差,導(dǎo)致不同步
氣象臺:今天天氣霧霾
氣象臺:今天天氣冰雹
丁昌江:你想被砸死嗎?反正我是不會去上課的
氣象臺:今天天氣霜凍
丁昌江:好冷啊,還是在宿舍睡覺吧
丁昌江:好冷啊,還是在宿舍睡覺吧
氣象臺:今天天氣霜凍
實(shí)現(xiàn)二:
class WeatherStation{
String []weathers={"晴天","暴雨","霜凍","臺風(fēng)","冰雹","霧霾"};
String curWeather;
Random random = new Random();
Student stu;
public void add(Student stu){
this.stu = stu;
}
public void startWork(){
new Thread(){
@Override
public void run() {
while(true){
updateWeather();
stu.observerWeather(curWeather);
//每 隔1~1.5秒更新一次天氣
int millis = random.nextInt(501)+1000;
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
private void updateWeather(){
int sel = random.nextInt(6);
curWeather = weathers[sel];
System.out.println("氣象臺:今天天氣"+curWeather);
}
class Demo01{
public static void main(String args[]){
WeatherStation ws = new WeatherStation ();
Student stu = new Student("丁昌江");
ws.add(stu);
ws.startWork();
}
}
結(jié)果:似乎好像已經(jīng)達(dá)到了目的,但是還有兩個(gè)局限,一:只能通知一個(gè)學(xué)生對象????二:只能通知學(xué)生嗎?其他群體咧,難道國家就只重視國學(xué)的小花朵嗎?
氣象臺:今天天氣霜凍
丁昌江:好冷啊,還是在宿舍睡覺吧
氣象臺:今天天氣霧霾
丁昌江:麻煩你幫我跟老師請個(gè)假,我中毒不輕
氣象臺:今天天氣晴天
丁昌江:天氣這么好,應(yīng)該去走走
氣象臺:今天天氣暴雨
丁昌江:這么大的雨就別去上課了
<h3>觀察者設(shè)計(jì)模式:</h3>
Weather接口:制定一個(gè)weather接口,只要實(shí)現(xiàn)了該接口的類都可以被氣象體通知
interface Weather {
void observerWeather (String cuWeather);
}
WeatherStation類:里面維護(hù)一個(gè)list來存儲當(dāng)前訂閱了氣象臺最新天氣的用戶,當(dāng)有新天氣時(shí),會遍歷該list去挨個(gè)通知用戶
class WeatherStation{
String []weathers={"晴天","暴雨","霜凍","臺風(fēng)","冰雹","霧霾"};
String curWeather;
Random random = new Random();
List<Weather> list = new ArrayList<Weather>();
public void add(Weather w){
list.add(w);
}
public void startWork(){
new Thread(){
@Override
public void run() {
while(true){
updateWeather();
//每 隔1~1.5秒更新一次天氣且遍歷通知list中的對象
for(Weather e:list){
e.observerWeather(curWeather);
}
int millis = random.nextInt(501)+1000;
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
private void updateWeather(){
int sel = random.nextInt(6);
curWeather = weathers[sel];
System.out.println("氣象臺:今天天氣"+curWeather);
}
}
Emp類:(同樣實(shí)現(xiàn)了Weather接口)
public class Emp implements Weather{
private String name;
public Emp(String name){
this.name = name;
}
@Override
public void observerWeather(String curWeather) {
switch(curWeather){
case "晴天":
System.out.println(this.name+":天氣這么好,肯定得上班呀");
break;
case "暴雨":
System.out.println(this.name+":下雨?已經(jīng)不錯(cuò)了,上班去吧");
break;
case "霜凍":
System.out.println(this.name+":買個(gè)棉大衣,上班去吧");
break;
case "臺風(fēng)":
System.out.println(this.name+":臺風(fēng)來了,你以為就不用上班了嗎?");
break;
case "冰雹":
System.out.println(this.name+":反正我是剛網(wǎng)購了一個(gè)頭盔");
break;
case "霧霾":
System.out.println(this.name+":來來來,每個(gè)人分一個(gè)防毒面具,上班去");
break;
}
}
}
Main類:主類
class Main{
public static void main(String args[]){
WeatherStation ws = new WeatherStation ();
ws.add(new Student("丁昌江"));
ws.add(new Emp("吳云飛"));
ws.startWork();
}
}
結(jié)果:
氣象臺:今天天氣冰雹
丁昌江:你想被砸死嗎?反正我是不會去上課的
吳云飛:反正我是剛網(wǎng)購了一個(gè)頭盔
氣象臺:今天天氣霜凍
丁昌江:好冷啊,還是在宿舍睡覺吧
吳云飛:買個(gè)棉大衣,上班去吧
氣象臺:今天天氣暴雨
丁昌江:這么大的雨就別去上課了
吳云飛:下雨?已經(jīng)不錯(cuò)了,上班去吧