状态模式(State Pattern)
|
1 2 3 4 |
定义:创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。 目的:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。 场景:游戏角色有跳跃、移动、射击、蹲下等状态设定,如果用if-else或者switch来进行判断, 在遇到组合动作的时候,判断会变得非常复杂难读,这时可以使用状态模式来实现。 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
const stateTable = { standing: { move: { message: '英雄开始移动' }, jump: { message: '英雄跳了起来', next: 'jumping' }, squat: { message: '英雄蹲下', next: 'squatting' }, shoot: { message: '英雄站立射击' } }, jumping: { move: { message: '英雄在空中调整方向' }, jump: { message: '英雄已经在空中,不能再次跳跃' }, squat: { message: '英雄在空中,不能蹲下' }, shoot: { message: '英雄在空中射击' }, land: { message: '英雄落地', next: 'standing' } }, squatting: { move: { message: '英雄蹲着缓慢移动' }, jump: { message: '英雄从蹲下状态起跳', next: 'jumping' }, squat: { message: '英雄已经蹲下' }, shoot: { message: '英雄蹲下射击' }, stand: { message: '英雄站了起来', next: 'standing' } } } class SuperHero { #state = 'standing' get state() { return this.#state } action(actionName) { const rule = stateTable[this.#state]?.[actionName] if (!rule) { console.log(`${this.#state} 状态不支持 ${actionName} 动作`) return this } console.log(rule.message) this.#state = rule.next ?? this.#state return this } } // 使用: const hero = new SuperHero() hero .action('move') .action('jump') .action('jump') .action('shoot') .action('land') .action('squat') .action('move') console.log(hero.state) // squatting // 输出: 英雄开始移动 英雄跳了起来 英雄已经在空中,不能再次跳跃 英雄在空中射击 英雄落地 英雄蹲下 英雄蹲着缓慢移动 |