1. 程式人生 > >觀察者模式(Observer Pattern)

觀察者模式(Observer Pattern)

servers his add pattern 一個 玩家 name list turn

觀察者模式又叫做訂閱/發布模式

  • 一個Subject,多Observer
  • 相互之間持有引用
  • Subject可以調用Observer的函數執行相應操作
  • Observer發生變動時也可以通知Subject讓其通知其他觀察者。

給個小栗子(效果圖如下)

技術分享圖片

目標被觀察者

技術分享圖片
 1 package ObserverPattern;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public abstract class Subject {
 7 
 8     //define an ArrayList to store observers
9 private List<Observer> observers = new ArrayList<>(); 10 public List<Observer> getObservers() { 11 return observers; 12 } 13 14 15 public void join(Observer observer) { 16 observers.add(observer); 17 } 18 19 public void quit(Observer observer) {
20 observers.remove(observer); 21 } 22 23 public abstract void notifyObservers(String name); 24 25 }
View Code

觀察者

技術分享圖片
package ObserverPattern;

public abstract class Observer {
    protected Subject subject;
    public Observer(Subject subject) {
        this.subject = subject;
    }
    
public abstract void sysMsg(String msg); public abstract void beAttacked(); public abstract String getName(); public abstract void setName(String name); }
View Code

戰況指揮中心

技術分享圖片
package ObserverPattern;

public class ActionControlCenter extends Subject {
    @Override
    public void notifyObservers(String name) {
        for (Observer observer : getObservers()) {
            if (name.equals(observer.getName()))
                observer.sysMsg(observer.getName() +"收到消息:堅持住,你隊友正在趕來!");
            else
                observer.sysMsg(observer.getName() +"收到消息:我方\"" + name + "\"正在受到攻擊,請盡快支援!");
        }
    }
}
View Code

玩家

技術分享圖片
package ObserverPattern;

public class Player extends Observer {

    public Player(Subject subject) {
        super(subject);
    }

    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    @Override
    public void beAttacked() {
        System.out.println(getName() + "收到消息:您正在受到攻擊!");
        subject.notifyObservers(getName());
    }
    @Override
    public void sysMsg(String msg) {
        System.out.println(msg);
    }
}
View Code

測試用例

package ObserverPattern;

import org.junit.Test;

public class MainTest {

    @Test
    public void myTest() {

        ActionControlCenter controlCenter = new ActionControlCenter();

        Player p1 = new Player(controlCenter);
        Player p2 = new Player(controlCenter);
        p1.setName("鄧艾");
        p2.setName("甄姬");


        controlCenter.join(p1);
        controlCenter.join(p2);

        p2.beAttacked();
    }

}

觀察者模式(Observer Pattern)