以下是详细的攻略:
学习JavaScript设计模式之状态模式
状态模式是什么?
状态模式是一种行为型设计模式,它允许对象在其内部状态更改时更改其行为。这个模式的主要想法是通过创建有限状态机来满足状态相关行为的需要。
状态模式的优点?
- 优化大型、复杂代码的结构。
- 减少了 if 语句的使用,使得代码更加简洁。
- 更好的可扩展性,可以方便地增加、删除或修改状态,而无需更改上下文代码。
- 状态类可以自行管理其状态,从而有助于减少上下文的复杂性。
状态模式的组成部分?
- State(状态):定义有限状态机中的状态,每个状态都实现自己的行为。
- Context(上下文):维护着一个 State 实例并将所有与状态相关的请求委托给当前状态。
- ConcreteState(具体状态):实现状态定义的行为。
状态模式的实现过程?
我们将使用一个由闹钟组成的示例来说明状态模式。
- 首先,定义一个 State 接口或抽象类,该接口或类声明了所有具体状态类所需实现的操作:
class State {
constructor(clock) {
this.clock = clock;
}
clickMode() {
throw new Error('This method must be overwritten!');
}
clickH() {
throw new Error('This method must be overwritten!');
}
clickM() {
throw new Error('This method must be overwritten!');
}
}
- 然后,定义所有具体状态类都需实现的操作:
class ClockState extends State {
clickMode() {
this.clock.setState(new AlarmState(this.clock));
}
clickH() {
throw new Error('This method must be overwritten!');
}
clickM() {
throw new Error('This method must be overwritten!');
}
}
class DisplayState extends State {
clickMode() {
this.clock.setState(new ClockState(this.clock));
}
clickH() {
this.clock.incrementHour();
}
clickM() {
this.clock.incrementMinute();
}
}
class AlarmState extends State {
clickMode() {
this.clock.setState(new DisplayState(this.clock));
}
clickH() {
this.clock.incrementAlarmHour();
}
clickM() {
this.clock.incrementAlarmMinute();
}
}
- 接着,定义上下文(闹钟)类,维护一个 State 实例并将所有与状态相关的请求委托给当前状态:
class Clock {
constructor() {
this.state = new DisplayState(this);
this.hour = 0;
this.minute = 0;
this.alarmHour = 0;
this.alarmMinute = 0;
}
setState(state) {
this.state = state;
}
incrementHour() {
this.hour++;
console.log(`Hours: ${this.hour}`);
}
incrementMinute() {
this.minute++;
console.log(`Minutes: ${this.minute}`);
}
incrementAlarmHour() {
this.alarmHour++;
console.log(`Alarm hours: ${this.alarmHour}`);
}
incrementAlarmMinute() {
this.alarmMinute++;
console.log(`Alarm minutes: ${this.alarmMinute}`);
}
mode() {
this.state.clickMode();
console.log(`Current state: ${this.state.constructor.name}`);
}
h() {
this.state.clickH();
}
m() {
this.state.clickM();
}
}
- 最后,使用上下文类实例来启动整个程序:
const clock = new Clock();
clock.h();
clock.m();
clock.mode();
clock.m();
clock.h();
clock.mode();
clock.mode();
clock.h();
这个示例充分展示了状态模式的能力:通过使用基类和 ConcreteState 向对象中添加新的状态并将其轻松重新配置,同时保持开放/封闭原则,即不会修改现有代码。
示例说明:
一个本地存储库示例说明了状态模式的优点。这个库有两个状态:
- 未初始化状态。
- 初始化状态。
当状态处于未初始化状态时,LocalStore 类的各种方法将不执行。当状态转换为初始化状态时,这些方法将执行,并且检查是否存在本地存储,如果它不存在,则进行初始化。
class LocalStoreUninitialized {
constructor() {
console.log('store is uninitialized');
}
init() {
console.log('Initializing store...');
const items = {};
localStorage.setItem('items', JSON.stringify(items));
this.localStore.setState(this.localStore.states.initialized);
}
addNew(item) {
throw new Error('Cannot call addNew() on an uninitialized store.');
}
deleteItem(id) {
throw new Error('Cannot call deleteItem() on an uninitialized store.');
}
getItems() {
throw new Error('Cannot call getItems() on an uninitialized store.');
}
}
class LocalStoreInitialized {
constructor() {
console.log('store is initialized');
}
init() {
console.log('store already initialized');
}
addNew(item) {
const items = JSON.parse(localStorage.getItem('items'));
items[item.id] = item;
localStorage.setItem('items', JSON.stringify(items));
console.log(`Added new item with id: ${item.id}`);
}
deleteItem(id) {
const items = JSON.parse(localStorage.getItem('items'));
delete items[id];
localStorage.setItem('items', JSON.stringify(items));
console.log(`Deleted item with id: ${id}`);
}
getItems() {
const items = JSON.parse(localStorage.getItem('items'));
console.log(items);
}
}
class LocalStore {
constructor() {
this.states = {
uninitialized: new LocalStoreUninitialized(),
initialized: new LocalStoreInitialized(),
};
this.setState(this.states.uninitialized);
}
setState(state) {
this.state = state;
this.state.localStore = this;
}
init() {
this.state.init();
}
addNew(item) {
this.state.addNew(item);
}
deleteItem(id) {
this.state.deleteItem(id);
}
getItems() {
this.state.getItems();
}
}
const localStore = new LocalStore();
localStore.init();
localStore.addNew({
id: 1,
name: 'Item 1',
});
localStore.getItems();
localStore.addNew({
id: 2,
name: 'Item 2',
});
localStore.getItems();
localStore.deleteItem(1);
localStore.getItems();
在上面的示例中,我们使用了两个具体状态(初始化和未初始化),以及 LocalStore 类的上下文来管理状态。当 LocalStore 类的实例创建时,它的状态被设置为未初始化。这意味着所有 LocalStore 上的方法都将抛出错误,直到 init 方法被调用并初始化了存储。初始化之后,状态被设置为初始化,并且上下文中的所有方法都可以正常工作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:学习JavaScript设计模式之状态模式 - Python技术站