ADT实现状态模式
状态模式和策略模式也有相似,他们都能实现某种算法,业务逻辑的切换。
状态模式:允许一个对象在其内部状态改变的时候改变他的行为,对象看起来似乎修改了他的类
- 状态决定行为,对象的行为由他的内部状态决定
- 对象在运行期间改变时,他的行为也跟着改变。 从表面上看,同一个对象,在不同时刻,行为不一样,就像类被改变。
不同:
策略模式通过客户端来切换不同的策略实现来改变算法;
状态模式通过修改内部状态来切换不同的行为方法。
举个栗子:
一个饮水机的例子,饮水机有未启动,制冷模式,制热模式。 可以用密封类来封装一个不同饮水机状态的ADT
sealed class WaterMachineState(open val machine:WaterMachine){
fun turnHeating(){
if(this !is Heating){
println("turn heating")
machine.state = machine.heating
} else {
println("The state is already heating mode.")
}
}
fun turnCooling(){
if(this !is Cooling){
println("turn cooling")
machine.state = machine.cooling
} else {
println("The state is already cooling mode.")
}
}
fun turnOff(){
if(this !is Off){
println("turn off")
machine.state = machine.off
} else {
println("The state is already off.")
}
}
}
class Off(override val machine:WaterMachine):WaterMachineState(machine)
class Heating(override val machine:WaterMachine):WaterMachineState(machine)
class Cooling(override val machine:WaterMachine):WaterMachineState(machine)
class WaterMachine{
var state:WaterMachineState
val off = Off(this)
val heating = Heating(this)
val cooling = Cooling(this)
init {
this.state = off
}
fun turnHeating(){
this.state.turnHeating()
}
fun turnCooling(){
this.state.turnCooling()
}
fun turnOff(){
this.state.turnOff()
}
}
- WaterMatchineState 是一个密封类,拥有一个构造参数WaterMachine对象。
- 在WaterMatchineState外部定义了三个状态Off,Heating,Cooling继承WaterMatchineState类的machine的成员属性和三个状态切换方法
- 在没个状态方法中,通过修改machine的状态state,来切换饮水机状态
办公是A类喜欢和冷水,早上调到制冷;B类人有吃泡面习惯,会调到制热;吃完泡面,下一个喝水同事切换到制冷。下班后,管理关闭电源。
enum class Moment {
EARLY_MORNING,//早上上班
DRINKING_WATER,//日常饮水
INSTANCE_NOODLES,//吃泡面
AFTER_WORK//下班
}
fun waterMachineOps(machine: WaterMachine, moment: Moment) {
when (moment) {
Moment.EARLY_MORNING,
Moment.DRINKING_WATER -> when (machine.state) {
!is Cooling -> machine.turnCooling()
}
Moment.INSTANCE_NOODLES -> when (machine.state) {
!is Heating -> machine.turnHeating()
}
Moment.AFTER_WORK -> when (machine.state) {
!is Off -> machine.turnOff()
}
else -> Unit
}
}
fun main() {
val machine = WaterMachine()
waterMachineOps(machine,Moment.DRINKING_WATER)
waterMachineOps(machine,Moment.INSTANCE_NOODLES)
waterMachineOps(machine,Moment.DRINKING_WATER)
waterMachineOps(machine,Moment.AFTER_WORK)
}