16观察者与状态模式代码实现

发布时间 2023-04-24 21:19:43作者: vbig

观察者模式代码实现

  • 选择合适的设计模式设计以下场景:
    猫(Cat)大叫一声,老鼠(Mouse)开始逃跑,主人(Master)被惊醒。
    要求:1. 要有联动性,老鼠和主人的行为是被动的;2. 考虑可扩展性,猫的叫声可能引起其他联动效应;3. 给出模式名称及定义,并结合场景绘制结构图。

观察者模式

  1. 类图:

  • 在某多人联机对战游戏中,多个玩家可以加入同一战队组成联盟,当战队中的某一成员受到敌人攻击时将给所有其他盟友发送通知,盟友收到通知后将做出响应。现使用观察者模式设计并实现该过程,以实现战队成员之间的联动。**
  1. 类图:

  1. 源代码:
  • AllyControlCenter
package com.fish.pattern.observer;  
  
import java.util.ArrayList;  
  
public abstract class AllyControlCenter {  
    protected String allyName;  //战队名  
    protected ArrayList<Observer> players = new ArrayList<>();  
  
    public String getAllyName() {  
        return allyName;  
    }  
  
    public void setAllyName(String allyName) {  
        this.allyName = allyName;  
    }  
  
    public void join(Observer obs){  
        players.add(obs); //加入战队  
        System.out.println(obs.getName()+"加入"+this.allyName+"战队");  
    }  
  
    public void quit(Observer obs){  
        players.remove(obs); //推出战队  
        System.out.println(obs.getName()+"退出"+this.allyName+"战队");  
    }  
  
    public abstract void notifyObserve(String name);  
}
  • ConcreteAllyControlCenter
package com.fish.pattern.observer;  
  
public class ConcreteAllyControlCenter extends AllyControlCenter {  
  
    public ConcreteAllyControlCenter(String allyName) {  
        this.allyName = allyName;  
        System.out.println(this.allyName+"战队组建成功!");  
    }  
  
    @Override  
    public void notifyObserve(String name) {  
        System.out.println(this.allyName+ "战队紧急通知,盟友"+name+"遭受攻击。。。");  
        for (Observer obs : players) {  
            if(!obs.getName().equalsIgnoreCase(name)){  
                obs.help();  
            }  
        }  
    }  
}
  • Observer
package com.fish.pattern.observer;  
  
public interface Observer {  
    String getName();  
    void setName(String name);  
    void help();  
    void beAttacked(AllyControlCenter acc);  
}
  • Player
package com.fish.pattern.observer;  
  
public class Player implements Observer{  
  
    private String name;  
  
    @Override  
    public String getName() {  
        return this.name=name;  
    }  
  
    @Override  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public void help() {  
        System.out.println("坚持住,"+this.name+"来救你!");  
    }  
  
    @Override  
    public void beAttacked(AllyControlCenter acc) {  
        System.out.println(this.name+"  被攻击!");  
        acc.notifyObserve(this.name);  
    }  
}
  • Client
package com.fish.pattern.observer;  
  
public class Client {  
    public static void main(String[] args) {  
        AllyControlCenter acc;  
        acc = new ConcreteAllyControlCenter("MyTeam");  
        Observer player1,player2,player3,player4;  
        player1 = new Player();  
        player1.setName("张三");  
        acc.join(player1);  
        player2 = new Player();  
        player2.setName("李四");  
        acc.join(player2);  
        player3 = new Player();  
        player3.setName("王五");  
        acc.join(player3);  
        player4 = new Player();  
        player4.setName("fish");  
        acc.join(player2);  
        acc.quit(player4);  
        player4.beAttacked(acc);  
    }  
}
  1. 运行结果:

状态模式代码实现

  • 用“状态模式”设计一个学生成绩的状态转换程序。本实例包含了“不及格”、“中等”和“优秀”3种状态,当学生的分数小于60分时为“不及格”状态,当分数大于等于60分且小于90分时为“中等”状态,当分数大于等于90分时为“优秀”状态。
  1. 类图:

  1. 源代码:
  • AbstractState
package com.fish.pattern.state;  
  
public abstract class AbstractState {  
    protected ScoreContext hj; //环境  
    protected String stateName; //状态名  
    protected int score; //分数  
  
    public abstract void checkState(); //检查当前状态  
  
    public void addScore(int x){  
        score+=x;  
        System.out.print("加上:"+x+"分,当前分数:"+score+"分");  
        checkState();  
        System.out.println(",当前状态为:"+hj.getState().stateName);  
  
    }  
}
  • HighState
package com.fish.pattern.state;  
  
public class HighState extends AbstractState{  
  
    public HighState(AbstractState state){  
        hj=state.hj;  
        stateName="优秀";  
        score=state.score;  
    }  
    @Override  
    public void checkState() {  
        if (score < 60) {  
            hj.setState(new LowState(this));  
        } else if (score >= 60) {  
            hj.setState(new MiddleState(this));  
        }  
    }  
}
  • LowState
package com.fish.pattern.state;  
  
public class LowState extends AbstractState{  
    //初始化  
    public LowState(ScoreContext h) {  
        hj = h;  
        stateName = "不及格";  
        score = 0;  
    }  
  
    public LowState(AbstractState state) {  
        hj = state.hj;  
        stateName = "不及格";  
        score = state.score;  
    }  
  
    @Override  
    public void checkState() {  
        if(score>=90){  
            hj.setState(new HighState(this));  
        }else if(score>=60){  
            hj.setState(new MiddleState(this));  
        }  
    }  
}
  • MiddleState
package com.fish.pattern.state;  
  
public class MiddleState extends AbstractState{  
    public MiddleState(AbstractState state){  
        hj=state.hj;  
        stateName="中等";  
        score=state.score;  
    }  
    @Override  
    public void checkState(){  
        if(score<60){  
            hj.setState(new LowState(this));  
        }else if(score>=90){  
            hj.setState(new HighState(this));  
        }  
    }  
}
  • ScoreContext
package com.fish.pattern.state;  
  
public class ScoreContext {  
    private AbstractState state;  
  
    public ScoreContext() {  
        state = new LowState(this);  
    }  
  
    public AbstractState getState() {  
        return state;  
    }  
  
    public void setState(AbstractState state) {  
        this.state = state;  
    }  
  
    public void add(int score){  
        this.state.addScore(score);  
    }  
}
  • Client
package com.fish.pattern.state;  
  
public class Client {  
    public static void main(String[] args) {  
        ScoreContext account=new ScoreContext();  
        System.out.println("学生成绩状态测试,初始分值为0:");  
        account.add(100);  
        account.add(-40);  
        account.add(-10);  
        account.add(50);  
        account.add(-25);  
    }  
}
  1. 运行结果: