狀態(tài)模式
狀態(tài)模式將狀態(tài)的切換交由具體的處理節(jié)點(diǎn)做判斷, 容器只提供執(zhí)行上下文
類模式實(shí)現(xiàn)
/**
* 處理節(jié)點(diǎn)類
*/
abstract class State{
state: string
next: State
constructor(state: string, next?: State){
this.state = state
this.next = next || this
}
// 狀態(tài)切換方法胳螟,交由具體的子類實(shí)現(xiàn)
abstract change():State
}
/**
* 狀態(tài)控制類
*/
class Store{
// 游標(biāo), 標(biāo)記下一可調(diào)用狀態(tài)
currentState: State
constructor(currentState: State){
this.currentState = currentState
}
run(){
// 修改當(dāng)前游標(biāo)指向
this.currentState = this.currentState.change()
}
}
/**
* 具體的狀態(tài)節(jié)點(diǎn)類實(shí)現(xiàn)
*/
class Success extends State{
constructor(next?: State){
const state = 'SUCCESS'
super(state, next)
}
// 子類實(shí)現(xiàn)具體的狀態(tài)處理
change(): State {
console.log(this.state)
return this.next
}
}
class Fail extends State{
constructor(next?: State){
const state = 'Fail'
super(state, next)
}
change(): State {
console.log(this.state)
return this.next
}
}
class Loading extends State{
success: State
fail: State
constructor(success?: State, fail?: State){
const state = 'Loading'
super(state)
this.success = success || this
this.fail = fail || this
}
change(): State {
console.log(`
---------- LOADING ----------
`)
this.next = Number.parseInt(`${Math.random() * 10}`) % 2 ? this.success : this.fail
return this.next
}
}
function stateMod(){
const success = new Success()
const fail = new Fail()
const loading = new Loading()
const store = new Store(loading)
success.next = loading
fail.next = loading
loading.success = success
loading.fail = fail
for(let i = 0; i < 10; i++){
store.run()
}
}
stateMod()
策略模式
調(diào)用具體執(zhí)行的函數(shù)的決策交由容器決定
類實(shí)現(xiàn)
// 決策容器
abstract class Strategy<T extends string>{
state: T
constructor(initState: T){
this.state = initState
}
// 狀態(tài)的的切換交由的策略決策處理
abstract strategy():void
}
type State = 'success' | 'fail' | 'loading'
class LoadData extends Strategy<State>{
loading: Function
success: Function
fail: Function
constructor(loading: Function, success: Function, fail: Function){
super('loading')
this.loading = loading
this.success = success
this.fail = fail
}
strategy(){
switch (this.state) {
case 'success':
this.success()
this.state = 'loading'
break;
case 'fail':
this.fail()
this.state = 'loading'
break;
case 'loading':
this.state = this.loading() ? 'success' : 'fail'
break;
}
}
}
function StrategyMod(){
// 具體的執(zhí)行不參與狀態(tài)的切換
const success = () => console.log('Success')
const fail = () => console.log('Fail')
const loading = () => {
console.log(`
---------- LOADING ----------
`)
return Number.parseInt(`${Math.random() * 10}`) % 2
}
const loadData = new LoadData(
loading,
success,
fail
)
for(let i = 0; i < 10; i++){
loadData.strategy()
}
}
StrategyMod()
函數(shù)方式
interface IStrategy<T>{
(s: T): T
}
type State = 'success' | 'fail' | 'loading'
/**
* 值容器
*/
class Container<T>{
state: T
constructor(state: T){
this.state = state
}
of(s: T){
return new Container(s)
}
map(cb:IStrategy<T>){
return this.of(cb(this.state))
}
}
type Warp<T extends string> = (s: T) => Warp<T>
function StrategyMod(){
// 具體的執(zhí)行不參與狀態(tài)的切換
const success = () => console.log('Success')
const fail = () => console.log('Fail')
const loading = () => {
console.log(`
---------- LOADING ----------
`)
return Number.parseInt(`${Math.random() * 10}`) % 2
}
// 決策函數(shù)
const loadData = function(s: State): State{
switch (s) {
case 'success':
success()
return 'loading'
case 'fail':
fail()
return 'loading'
case 'loading':
return loading() ? 'success' : 'fail'
}
}
const list = new Array(10).fill('')
list.reduce<Container<State>>((acc) => acc.map(loadData), new Container<State>('success'))
}
StrategyMod()
總結(jié)
策略模式與狀態(tài)模式,關(guān)注的是狀態(tài)切換的控制權(quán)嘉竟。
- 策略模式由中心容器根據(jù)輸入控制具體的執(zhí)行函數(shù)舍扰,控制權(quán)在容器中
- 狀態(tài)模式由當(dāng)前的執(zhí)行節(jié)點(diǎn)控制具體的狀態(tài)設(shè)置, 控制權(quán)在狀態(tài)節(jié)點(diǎn)中
策略模式更中心化,狀態(tài)模式更分布式陵且。