18. 状态模式(State)
18. 状态模式(State)
问题:对象有大量状态判断逻辑(长 switch),状态间转换复杂。
核心:把每个状态封装成独立类,状态切换就是切换当前状态对象。
class Draft {
constructor(doc) { this.doc = doc; }
publish() {
console.log('提交审核');
this.doc.setState(new Moderation(this.doc));
}
reject() { console.log('草稿不能被拒绝'); }
}
class Moderation {
constructor(doc) { this.doc = doc; }
publish() {
console.log('审核通过,已发布');
this.doc.setState(new Published(this.doc));
}
reject() {
console.log('审核未通过,退回草稿');
this.doc.setState(new Draft(this.doc));
}
}
class Published {
constructor(doc) { this.doc = doc; }
publish() { console.log('已发布,无需重复操作'); }
reject() {
console.log('撤回发布');
this.doc.setState(new Draft(this.doc));
}
}
class Document {
#state;
constructor() { this.#state = new Draft(this); }
setState(s) { this.#state = s; }
publish() { this.#state.publish(); }
reject() { this.#state.reject(); }
}
const doc = new Document();
doc.publish(); // 提交审核
doc.publish(); // 审核通过,已发布
doc.reject(); // 撤回发布package state
import "fmt"
type Document struct {
state State
}
func (d *Document) SetState(s State) { d.state = s }
func (d *Document) Publish() { d.state.Publish() }
func (d *Document) Reject() { d.state.Reject() }
type State interface {
Publish()
Reject()
}
type Draft struct{ doc *Document }
func (s Draft) Publish() {
fmt.Println("提交审核")
s.doc.SetState(Moderation{doc: s.doc})
}
func (s Draft) Reject() { fmt.Println("草稿不能被拒绝") }
type Moderation struct{ doc *Document }
func (s Moderation) Publish() {
fmt.Println("审核通过,已发布")
s.doc.SetState(Published{doc: s.doc})
}
func (s Moderation) Reject() {
fmt.Println("审核未通过,退回草稿")
s.doc.SetState(Draft{doc: s.doc})
}
type Published struct{ doc *Document }
func (s Published) Publish() { fmt.Println("已发布,无需重复操作") }
func (s Published) Reject() {
fmt.Println("撤回发布")
s.doc.SetState(Draft{doc: s.doc})
}