阅读 159

DBA学RUST设计模式--状态模式

DBA学RUST设计模式--状态模式

一个对象会有不同的状态,不同的操作会影响状态,同时状态改变,也会影响对象和业务流程。例如,薛定谔的猫有3种状态:生、死、不确定,假设3种状态可转换.

名称为CatState的trait描述了对猫的所有状态操作:

trait CatState {
fn make_live(self: Box<Self>) -> Box<dyn CatState>; //使猫生fn make_dead(self: Box<Self>) -> Box<dyn CatState>; //使猫死fn make_uncertain(self: Box<Self>) -> Box<dyn CatState>; //使猫变得不确定}

 

接下来,定义一个结构体猫,该结构体包含一个属性:state。结构体描述了猫的状态信息,由于状态数据长度的不确定性和,因此使用存储在堆上的Box包裹trait方式定义。任何想要获取或者设置state值,都要实现CatState这个trait。

复制代码

struct Cat{
state: Option<Box<dyn CatState>>,
}//Cat实现类,前台调用,因此使用mut传递前端参数,获取可变引用。impl Cat {
fn make_live_impl(&mut self) {if let Some(s) = self.state.take() {//此处的s也即self,为前端实例化后的对象,该对象需实现trait:CatStateself.state = Some(s.make_live())
}
}
fn make_dead_impl(&mut self) {if let Some(s) = self.state.take() {
self.state = Some(s.make_dead())
}
}
fn make_uncertain_impl(&mut self) {if let Some(s) = self.state.take() {
self.state = Some(s.make_uncertain())
}
}
}

复制代码

 


接下来,需要实现具体状态的转换规则,具体规则需根据业务逻辑自行设定这里设置了3种状态,分别为live_state、dead_state、uncertain_state,每种状态下分别实现了trait接口全部功能,包含了相应的转换处理规则。这里的规则是,live -> dead -> uncertain -> live


这里使用了Box<Self>,获取所有权,防止实例化后的struct有多个状态。

复制代码

struct live_state {}struct dead_state {}struct uncertain_state {}

impl CatState for live_state {
fn make_live(self: Box<Self>) -> Box<dyn CatState> {
println!("本来就是活的!");
self
}
fn make_dead(self: Box<Self>) -> Box<dyn CatState> {
println!("已使猫死亡!");
Box::new(dead_state {}) //有了这里,就省去了前台的if语句}
fn make_uncertain(self: Box<Self>) -> Box<dyn CatState> {
println!("live状态不可转uncertain");
self
}
}

复制代码

 

同理实现其余状态

复制代码

impl CatState for dead_state {
fn make_live(self: Box<Self>) -> Box<dyn CatState> {
println!("已经死亡,无法复活");
self
}
fn make_dead(self: Box<Self>) -> Box<dyn CatState> {
println!("本来就是死的!");
self
}
fn make_uncertain(self: Box<Self>) -> Box<dyn CatState> {
println!("成功设置为uncertain!");
Box::new(uncertain_state {})
}
}

impl CatState for uncertain_state {
fn make_live(self: Box<Self>) -> Box<dyn CatState> {
println!("成功复活");
Box::new(live_state {})
}
fn make_dead(self: Box<Self>) -> Box<dyn CatState> {
println!("无法从uncertain转dead");
self
}
fn make_uncertain(self: Box<Self>) -> Box<dyn CatState> {
println!("本来就是uncertain");
self
}
}

复制代码

 

前台调用

let mut special_cat = Cat{state:Some(Box::new(dead_state{}))};
special_cat.make_live_impl();
special_cat.make_uncertain_impl();

 

总结
状态模型主要是要抽象出影响状态的行为和对应的状态值,一般是1对1对应关系。应依据状态行为编写trait接口,有多少行为就编写多少接口。

前端初始化运行,通过调取不同的函数,在实现类内部改变Cat的状态。由于cat的实现类和实例化类都实现了CatState接口,使上述实现成为可能。

来源https://www.cnblogs.com/ggcfpe/p/14934538.html

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐