設計模式--直譯器模式和狀態模式

禿頭男的春天發表於2020-10-27

1、直譯器模式

package com.yqj.pattern.memento;

import java.util.ArrayList;
import java.util.List;

//原始物件
class GameRole{
    private int vit;
    private int def;

    public GameRole(int vit, int def) {
        this.vit = vit;
        this.def = def;
    }

    public Memento createMemento(){
        return new Memento(vit,def);
    }

    public void recoverMenmento(Memento memento){
        vit = memento.getVit();
        def = memento.getDef();
    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }

    @Override
    public String toString() {
        return "GameRole{" +
                "vit=" + vit +
                ", def=" + def +
                '}';
    }
}

//備忘錄物件
class Memento{
    private int vit;
    private int def;

    public Memento(int vit, int def) {
        this.vit = vit;
        this.def = def;
    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }
}

class Caretaker{
    //在集合中會有多個備忘錄物件
    private List<Memento> mementos = new ArrayList<>();

    //將某個備忘錄物件加入集合
    public void add(Memento memento){
        mementos.add(memento);
    }

    //獲取第index個原始物件的備忘錄物件(儲存的狀態)
    public Memento get(int index){
        return mementos.get(index);
    }

}

public class Client {
    public static void main(String[] args) {
        GameRole gameRole = new GameRole(100,100);
        Caretaker caretaker = new Caretaker();
        caretaker.add(gameRole.createMemento());
        gameRole.setVit(70);
        gameRole.setDef(80);
        caretaker.add(gameRole.createMemento());
        gameRole.setVit(60);
        gameRole.setDef(70);
        caretaker.add(gameRole.createMemento());

        System.out.println(gameRole);
        gameRole.recoverMenmento(caretaker.get(1));
        System.out.println(gameRole);
        gameRole.recoverMenmento(caretaker.get(0));
        System.out.println(gameRole);
    }
}

2、狀態模式

    package com.yqj.pattern.state;
    
    import java.util.Random;
    
    class Activity{
        //當前狀態
        private State state = null;
        //獎品數量
        private int count = 0;
        //錢數
        private int money = 0;
    
        //狀態
        private State noRaffleState = new NoRaffleState(this);
        private State canRaffleState = new CanRaffleState(this);
        private State dispenseState = new DispenseState(this);
        private State dispenseOutState = new DispenseOutState(this);
    
        public Activity(int count, int money) {
            this.state = getNoRaffleState();
            this.count = count;
            this.money = money;
        }
    
        //扣錢
        public void deduceMoney(){
            state.deduceMoney();
        }
    
        //抽獎
        public void raffle(){
            if(state.raffle()){
                state.dispensePrize();
            }
        }
    
        public State getState() {
            return state;
        }
    
        public void setState(State state) {
            this.state = state;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public int getMoney() {
            return money;
        }
    
        public void setMoney(int money) {
            this.money = money;
        }
    
        public State getNoRaffleState() {
            return noRaffleState;
        }
    
        public State getCanRaffleState() {
            return canRaffleState;
        }
    
        public State getDispenseState() {
            return dispenseState;
        }
    
        public State getDispenseOutState() {
            return dispenseOutState;
        }
    
    }
    
    
    //抽象類,定義各個狀態都需要實現的不同行為
    abstract class State{
        public abstract void deduceMoney();
        public abstract boolean raffle();
        public abstract void dispensePrize();
    }
    
    class NoRaffleState extends State{
    
        private Activity activity;
    
        public NoRaffleState(Activity activity) {
            this.activity = activity;
        }
    
        @Override
        public void deduceMoney() {
            if(activity.getCount()>0){
                int currentMoney = activity.getMoney();
                if(currentMoney - 50 >=0){
                    activity.setMoney(currentMoney - 50);
                    activity.setState(activity.getCanRaffleState());
                    System.out.println("成功扣除50塊錢,餘額:"+(activity.getMoney()));
                }else {
                    System.out.println("餘額不足,抽獎結束");
                    System.exit(0);
                }
            }else {
                activity.setState(activity.getDispenseOutState());
            }
        }
    
        @Override
        public boolean raffle() {
            System.out.println("請先扣錢");
            return false;
        }
    
        @Override
        public void dispensePrize() {
            System.out.println("請先扣錢");
        }
    }
    
    class CanRaffleState extends State{
    
        private Activity activity;
    
        public CanRaffleState(Activity activity) {
            this.activity = activity;
        }
    
        @Override
        public void deduceMoney() {
            System.out.println("已扣錢");
        }
    
        @Override
        public boolean raffle() {
            System.out.println("正在抽獎");
            Random random = new Random();
            int num = random.nextInt(10);
            if (num == 0){
                System.out.println("抽獎成功");
                activity.setCount(activity.getCount()-1);
                activity.setState(activity.getDispenseState());
                return true;
            }
            System.out.println("很遺憾,沒有抽到獎品");
            activity.setState(activity.getNoRaffleState());
            return false;
        }
    
        @Override
        public void dispensePrize() {
            System.out.println("請先抽獎");
        }
    }
    
    class DispenseState extends State{
    
        private Activity activity;
    
        public DispenseState(Activity activity) {
            this.activity = activity;
        }
    
        @Override
        public void deduceMoney() {
            System.out.println("已扣錢");
        }
    
        @Override
        public boolean raffle() {
            System.out.println("已抽獎");
            return false;
        }
    
        @Override
        public void dispensePrize() {
            if (activity.getCount() > 0){
                System.out.println("傳送獎品,可以再次抽獎");
                activity.setState(activity.getNoRaffleState());
            }else {
                System.out.println("傳送獎品,獎品已抽完");
                activity.setState(activity.getDispenseOutState());
            }
        }
    }
    
    class DispenseOutState extends State{
    
        private Activity activity;
    
        public DispenseOutState(Activity activity) {
            this.activity = activity;
        }
    
        @Override
        public void deduceMoney() {
            System.out.println("獎品已抽完,無法扣款");
        }
    
        @Override
        public boolean raffle() {
            System.out.println("獎品已抽完,無法抽獎");
            return false;
        }
    
        @Override
        public void dispensePrize() {
            System.out.println("獎品已抽完");
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            Activity activity = new Activity(2,500);
            for (int i = 0; i < 30; i++) {
                System.out.println("-----第"+(i+1)+"次抽獎-----");
                //扣錢
                activity.deduceMoney();
                //參與抽獎
                activity.raffle();
            }
        }
    }

相關文章