Strategy Pattern模式(策略模式)

2020-12-26  本文已影响0人  涅槃快乐是金

策略模式(Strategy Pattern):一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

介绍

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

示例

Hand.ts 表示猜拳游戏中的手势类
export default class Hand {
    public HANDVALUE_GUU = 0;//表示石头的值
    public HANDVALUE_CHO = 1;//表示剪刀的值
    public HANDVALUE_PAA = 2;//表示布的值

    private name: Array<string> = ["石头", "剪刀", "布"];

    private handValue: number;
    constructor(handValue: number) {
        this.handValue = handValue;
    }

    public getHand(handValue: number): Hand {
        return new Hand(handValue);
    }

    public isStrongerThan(h: Hand): boolean {
        return this.fight(h) == 1;
    }

    public isWeakerThan(h: Hand): boolean {
        return this.fight(h) == -1;
    }

    private fight(h: Hand): number {
        if (this.handValue == h.handValue) {
            return 0;
        } else if ((this.handValue + 1) % 3 > h.handValue) {
            return 1;
        } else {
            return -1;
        }
    }
    public toString(): string {
        return this.name[this.handValue];
    }
}
Strategy.ts 表示猜拳游戏中的策略的类
import Hand from "./Hand";

export interface Strategy {
    nextHand(): Hand;
    study(win: boolean): void;
}
WinningStrategy.ts 表示如果这局获胜,那么下一局同样手势的类
import { Strategy } from "./type";
import Hand from "./Hand";

export default class WinningStrategy implements Strategy {
    private win: boolean = false;
    private prevHand: Hand;
    constructor() {
    }
    public nextHand(): Hand {
        if (!this.win) {
            const random = Math.floor(Math.random() * 3);
            const hand = new Hand(random);
            this.prevHand = hand.getHand(random);
        }
        return this.prevHand;
    }
    public study(win: boolean) {
        this.win = win;
    }
}
RandomStragegy.ts 表示每次都随机手势
import { Strategy } from "./type";
import Hand from "./Hand";

export default class RandomStragegy implements Strategy {
    constructor() {
    }
    public nextHand(): Hand {
        const random = Math.floor(Math.random() * 3);
        const hand = new Hand(random);
        return hand.getHand(random);
    }
    public study(win: boolean) {
    }
}
Player.ts 猜拳游戏的选手类
import { Strategy } from "./type";
import Hand from "./Hand";

export default class Play {
    private name: string;
    private winCount: number = 0;
    private loseCount: number = 0;
    private gameCount: number = 0;
    private stragegy: Strategy
    constructor(name: string, stragegy: Strategy) {
        this.name = name;
        this.stragegy = stragegy;
    }

    public nextHand(): Hand {
        return this.stragegy.nextHand()
    }

    public win(): void {
        this.stragegy.study(true);
        this.winCount++;
        this.gameCount++;
    }
    public lose(): void {
        this.stragegy.study(false);
        this.loseCount++;
        this.gameCount++;
    }
    public even() {
        this.gameCount++;
    }
    public toString(): string {
        return `[${this.name}:${this.gameCount} games,${this.winCount} win,${this.loseCount} lose]`
    }
}
index.ts
import Play from "./Play";
import WinningStrategy from "./WinningStrategy";
import RandomStragegy from "./RandomStragegy";

const play1: Play = new Play("Trao", new WinningStrategy());//坚持上一次赢
const play2: Play = new Play("Haha", new RandomStragegy());//随机
for (let i = 0; i < 20; i++) {
    const nextHand1 = play1.nextHand();
    const nextHand2 = play2.nextHand();
    if (nextHand1.isStrongerThan(nextHand2)) {
        console.log(`Winner ${play1.toString()} ${nextHand1.toString()}`);
        play1.win();
        play2.lose();
    } else if (nextHand2.isStrongerThan(nextHand1)) {
        console.log(`Winner ${play2.toString()}  ${nextHand2.toString()}`);
        play2.win();
        play1.lose();
    } else {
        console.log(`Even... ${nextHand1.toString()}`);
        play2.even();
        play1.even();
    }
}
result
Even... 布
Even... 布
Even... 布
Even... 剪刀
Winner [Haha:5 games,1 win,0 lose]  剪刀
Winner [Trao:6 games,1 win,1 lose] 剪刀
Even... 剪刀
Even... 剪刀
Even... 剪刀
Winner [Trao:10 games,2 win,1 lose] 剪刀
Even... 剪刀
Winner [Trao:12 games,3 win,1 lose] 剪刀
Even... 剪刀
Winner [Trao:14 games,4 win,1 lose] 剪刀
Winner [Trao:15 games,5 win,1 lose] 剪刀
Even... 剪刀
Even... 剪刀
Winner [Trao:18 games,6 win,1 lose] 剪刀
Winner [Trao:19 games,7 win,1 lose] 剪刀
Even... 剪刀
————————————Result————————————————
Result [Trao:20 games,7 win,1 lose]
Result [Haha:20 games,1 win,7 lose]

类图

角色

上一篇下一篇

猜你喜欢

热点阅读