17 Rust的面向对象编程特性
面向对象编程(OOP)是一种模式话编程方式
17.3 面向对象设计模式的实现
状态模式是一个面向对象设计模式。它的关键在于一个值有很多内部状态,它们叫状态对象,同时每个状态对象都拥有自己的行为以及何时转变为另一种状态。值对状态对象的行为以及状态何时转移毫不知情
使用状态模式的好处在于业务需求发生变化时,我们不需要改变值或者操作值的代码。只需要转变状态对象的状态(包括增加状态对象)或变更每个状态对象的行为即可
我们来通过一个博客发布流程来说明上述功能
博客的功能:
1.博文从空白草案开始
2.一旦草案完成,请求审核博文
3.一旦博文过审,发表博文
4.打印发表的博文
我们将在blog库crate 中实现它
use blog::Post;
fn main() {
let mut post = Post::new();
post.add_text("I ate a salad for lunch today");
assert_eq!("",post.content());
post.request_review();
assert_eq!("",post.content());
post.approve();
assert_eq!("I ate a salad for lunch today", post.content());
}
我们期望的实现如上,在这里我们可以发现post这个值他有几个内部状态,我们结下来会更加深刻的认识到这一点,测试函数仅仅是为了测试代码如期运行
现在让我们从基本的单位开始构建程序
定义Post并新建一个草案状态的实例
pub struct Post {
state: Option<Box<dyn State>>,
content:String,
}
impl Post {
pub fn new()->Post{
Post{
state:Some(Box::new(Draft{})),
content:String::new(),
}
}
}
trait State {}
struct Draft {}
impl State for Draft {}
很好,我们创建了这个值的类型Post(调用的时候实例化就行),它是一个结构体,包含两个字段一个内容一个状态,状态还是可变的,在这里我们使用了一个Option枚举,里面装了一个trait对象 Box,没错,这里的操作和上一节中学过的内容时一致的
接着我们为Post定义了一个关联函数,函数返回的是一个Post实例,Post实例中content字段我们使用了String::from创建了一个空字符串&