当前位置: 首页 > news >正文

网站开发流程主要分成什么上海专业seo

网站开发流程主要分成什么,上海专业seo,wordpress能做商城吗,南京专业网站制作公司喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 17.3.1. 状态模式 状态模式(state pattern) 是一种面向对象设计模式,指的是一个值拥有的内部状态由数个状态对象&#xff08…

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
请添加图片描述

17.3.1. 状态模式

状态模式(state pattern) 是一种面向对象设计模式,指的是一个值拥有的内部状态由数个状态对象(state object) 表达而成,而值的行为随着内部状态的改变而改变。

使用状态模式意味着:业务需求变化时,不需要修改持有状态的值的代码,或者是使用这个值的代码;只需要更新状态对象内部的代码,以改变其规则,或者是增加一些新的状态对象。

看个例子:

博客文章一开始是一个空草稿。草稿完成后,要求对该帖子进行审查。当帖子获得批准后,就会发布。只有已发布的博客帖子才会返回要打印的内容,因此不会意外发布未经批准的帖子。

main.rs:

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::new创建新的博客文章草稿。首先创建一个Post类型的实例,命名为post。它是可变的,因为处于草稿状态的文章还可以修改
  • 然后通过Post上的add_text方法增加了"I ate a salad for lunch today"这句话
  • 接下来使用request_review方法请求审批
  • 最后使用approve方法获得审批通过

PS:添加的assert_eq!在代码中用于演示目的。单元测试可能包含断言草稿博客文章从content方法返回一个空字符串,但我们不打算为此示例编写测试。

lib.rs:

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(),}}pub fn add_text(&mut self, text: &str) {self.content.push_str(text);}pub fn content(&self) -> &str {""}pub fn request_review(&mut self) { if let Some(s) = self.state.take() { self.state = Some(s.request_review()) } }pub fn approve(&mut self) { if let Some(s) = self.state.take() { self.state = Some(s.approve()) } }
}trait State {fn request_review(self: Box<Self>) -> Box<dyn State>;fn approve(self: Box<Self>) -> Box<dyn State>;
}struct Draft {}impl State for Draft {fn request_review(self: Box<Self>) -> Box<dyn State> {Box::new(PendingReview {})}fn approve(self: Box<Self>) -> Box<dyn State> { Box::new(Published {}) }
}struct PendingReview {}impl State for PendingReview {fn request_review(self: Box<Self>) -> Box<dyn State> {self}fn approve(self: Box<Self>) -> Box<dyn State> { Box::new(Published {}) }
}struct Published {} impl State for Published { fn request_review(self: Box<Self>) -> Box<dyn State> { self } fn approve(self: Box<Self>) -> Box<dyn State> { self } 
}
  • Post结构体有两个字段,一个字段是state,用于存储文章当下的状态,它一共有三种状态:草稿、等待审批和已发布。Box<dyn State>代表只要是实现了State trait的类型就可以存入
    通过这个字段,Post类型能在内部管理状态与状态之间的变化,这个状态的变化是通过用户调用Post上的方法实现的,而用户只能通过调用这些方法来改变值(因为Post下的字段未设为公开,所以用户没办法直接修改字段的值)。

  • 下文通过impl块为Post实现了一些方法:

    • new函数用于创建一个Post类型的实例,其初始的content值是一个空的字符串;初始的state处于草稿状态,所以state存储的是Draft结构体(下文有讲)

    • add_text会往content字段使用pusth_str方法来添加内容

    • 即使我们调用了add_text并向帖子添加了一些内容,我们仍然希望content方法返回一个空字符串切片,因为帖子仍处于草稿状态。

    • request_review会提取出state字段下的状态,取出来之后,State就会暂时变为None,因为所有权被移动出来了。这个时候调用state上的request_review方法来请求审批。
      stateDraft状态时,就会调用Draft结构体上的request_review方法(下文有讲),把state字段的值从Draft变为了PendingReview,把状态更新回state上。

  • approve表示审批通过,其写法跟request_review差不多,把状态取出来,调用self上的approve方法来更新状态。

  • State trait目前定义了两个方法,只有签名,没有具体实现:

    • request_review表示请求审批
    • approve表示审批通过
      PS:注意它的签名的参数是Box<self>,与selfmut self有区别,Box<self>意味着它只能被包裹着当前类型的Box实例,它会在调用过程中获取Box(self)的所有权,并使旧的实效,从而修改状态。
  • Draft用于表示草稿状态,不需要实际的内容,所以只要声明一个没有字段的结构体即可

  • 通过impl块为Draft实现了State trait:

    • request_review表示请求审批,把值变为了PendingReview
    • approve表示审批通过。由于approve在此时没用,只需要把本身传回去即可,所以返回值是self
  • PendingReviewing用于表示等待审批,不需要实际的内容,所以只要声明一个没有字段的结构体即可

  • 通过impl块为PendingReview实现了State trait:

    • request_review表示请求审批,此时状态不会变,只需要把本身传回去即可,所以返回值是self
    • approve表示审批通过,返回Published结构体。
  • Published用于表示已发表,不需要实际的内容,所以只要声明一个没有字段的结构体即可

  • 通过impl块为Published实现了State trait。但是它都处于已发布的状态了,所以request_reviewapprove都没啥用,直接返回本身self就行。


我们为什么不使用枚举类型的变体作为帖子状态?这当然是一个可能的解决方案,但它的其缺点之一是使用枚举是每个检查枚举值的地方都需要一个match表达式或类似的表达式来处理每个可能的变体。


这样写会存在很多重复的代码,有些代码根本没用;但是它的优点也很明显:无论状态值是什么Post上的request_review方法都不需要改变,每个状态都负责自己的运行规则。

这里还有content方法还需要修改,我们想要在发布状态下使它可见,而其他两种情况下看不到。一样可以使用面向对象的设计模式。以下是原来的代码:

pub fn content(&self) -> &str {""
}

首先在State trait下定义content方法:

trait State {fn request_review(self: Box<Self>) -> Box<dyn State>;fn approve(self: Box<Self>) -> Box<dyn State>;fn content<'a>(&self, post: &'a Post) -> &'a str {""}
}

写了个默认实现,返回空字符串。注意这里要使用生命周期,因为接收的是Post的引用,然后返回的可能是Post中某一部分的引用,所以返回值的生命周期和Post参数的生命周期是相关联的。

对于DraftPendingReview来说默认实现就可以满足需求了。只需要在Published中写一个方法覆盖默认实现:

impl State for Published { fn request_review(self: Box<Self>) -> Box<dyn State> { self } fn approve(self: Box<Self>) -> Box<dyn State> { self } fn content<'a>(&self, post: &'a Post) -> &'a str {&post.content}
}

最后修改Post上的content方法:

impl Post {pub fn new() -> Post {Post {state: Some(Box::new(Draft {})),content: String::new(),}}pub fn add_text(&mut self, text: &str) {self.content.push_str(text);}pub fn content(&self) -> &str {self.state.as_ref().unwrap().content(&self)}pub fn request_review(&mut self) { if let Some(s) = self.state.take() { self.state = Some(s.request_review()) } }pub fn approve(&mut self) { if let Some(s) = self.state.take() { self.state = Some(s.approve()) } }
}

我们需要先看Option里面值的引用,所以说调用了as_ref方法得到Option<&T>,为了解包必须写一步错误处理,用unwrap即可。最后就调用content方法,根据所处的状态不同,content的具体实现也会有所不同。

17.3.2. 状态模式的取舍权衡

状态模式的优点如上所见:无论状态值是什么Post上的request_review方法都不需要改变,每个状态都负责自己的运行规则。

但它的缺点也比较明显:

  • 需要重复实现一些逻辑代码
  • 某些状态之间是相互耦合的,如果我们新增一个状态,这时候跟它相关联的代码就需要修改

17.3.3. 将状态和行为编码为类型

如果我们严格按照面向对象的模式写当然是可行的,但是发挥不出Rust的全部威力。

下面我们会结合Rust的特点来修改,具体来说就是把状态和行为改为具体的类型。Rust类型检查系统会通过编译时错误来阻止用户使用无效的状态。

修改后的代码如下:
lib.rs:

pub struct Post {content: String,
}pub struct DraftPost {content: String,
}impl Post {pub fn new() -> DraftPost {DraftPost {content: String::new(),}}pub fn content(&self) -> &str {&self.content}
}impl DraftPost {pub fn add_text(&mut self, text: &str) {self.content.push_str(text);}pub fn request_review(self) -> PendingReviewPost {PendingReviewPost {content: self.content,}}
}pub struct PendingReviewPost {content: String,
}impl PendingReviewPost {pub fn approve(self) -> Post {Post {content: self.content,}}
}
  • 声明了PostDraftPost两个结构体,这两者都有一个存储String类型的content字段

  • 通过impl块写了Postnew方法和content方法:

    • new方法会创建一个空的DraftPost结构体
    • content方法就会返回本身的content字段的值
  • 通过impl块写了DraftPost的方法:

    • add_text方法用于给DraftPostcontent添加文字
    • request_review方法用于请求审批,调用这个方法就会返回另一个状态PendingReviewPost,表示正在审批中。这个状态是在下文定义的
  • 声明了PendingReviewPost结构体,有一个存储String类型的content字段。通过impl在它上面写了一个approve方法用于通过审批

这里的Post就指正式发布之后的PostDraftPost就代表还处于草稿状态的文章,PendingReviewPost表示正在审批的文章。审批成功就会把content的值返回到Postcontent字段里以供使用。

这样写不会出现意外的情况,因为只有通过审批正式发布的状态Post才有content方法来获取文章。

此时的main.rs写法也需要小改:

use blog::Post;fn main() {let mut post = Post::new();post.add_text("I ate a salad for lunch today");let post = post.request_review();let post = post.approve();assert_eq!("I ate a salad for lunch today", post.content());
}

17.3.4. 总结

Rust不仅能够实现面向对象的设计模式,还可以支持更多的模式。例如将状态和行为编码为类型。

面对对象的经典模式并不总是Rust编程实践中的最佳选择,因为Rust具有其他面向对象语言所没有的所有权特性。


文章转载自:
http://nitty.mrfr.cn
http://chypre.mrfr.cn
http://docket.mrfr.cn
http://pastedown.mrfr.cn
http://subregion.mrfr.cn
http://bosky.mrfr.cn
http://almacantar.mrfr.cn
http://tint.mrfr.cn
http://puzzolana.mrfr.cn
http://special.mrfr.cn
http://forcible.mrfr.cn
http://dextro.mrfr.cn
http://respectful.mrfr.cn
http://litigiosity.mrfr.cn
http://park.mrfr.cn
http://grecism.mrfr.cn
http://anselm.mrfr.cn
http://numeraire.mrfr.cn
http://pookoo.mrfr.cn
http://lampooner.mrfr.cn
http://vexillology.mrfr.cn
http://paleographic.mrfr.cn
http://proposed.mrfr.cn
http://paotou.mrfr.cn
http://wincey.mrfr.cn
http://discarnate.mrfr.cn
http://busty.mrfr.cn
http://saltillo.mrfr.cn
http://vomiturition.mrfr.cn
http://stardom.mrfr.cn
http://pesthole.mrfr.cn
http://anthropocentric.mrfr.cn
http://sanctifier.mrfr.cn
http://leucite.mrfr.cn
http://majolica.mrfr.cn
http://impulsion.mrfr.cn
http://topographical.mrfr.cn
http://scrotocele.mrfr.cn
http://puppyish.mrfr.cn
http://droplet.mrfr.cn
http://barranquilla.mrfr.cn
http://drygoods.mrfr.cn
http://teleputer.mrfr.cn
http://perversive.mrfr.cn
http://evermore.mrfr.cn
http://laciness.mrfr.cn
http://tersanctus.mrfr.cn
http://nationally.mrfr.cn
http://irid.mrfr.cn
http://kinetosis.mrfr.cn
http://atmologist.mrfr.cn
http://hayley.mrfr.cn
http://pinholder.mrfr.cn
http://resilience.mrfr.cn
http://ratomorphic.mrfr.cn
http://masticate.mrfr.cn
http://unartificial.mrfr.cn
http://interoffice.mrfr.cn
http://capercaillye.mrfr.cn
http://stitchwork.mrfr.cn
http://pitfall.mrfr.cn
http://patroness.mrfr.cn
http://unmistakable.mrfr.cn
http://bluppy.mrfr.cn
http://zoophily.mrfr.cn
http://gloze.mrfr.cn
http://kumquat.mrfr.cn
http://breechloading.mrfr.cn
http://corvet.mrfr.cn
http://sutteeism.mrfr.cn
http://wordiness.mrfr.cn
http://sherd.mrfr.cn
http://slipknot.mrfr.cn
http://modulus.mrfr.cn
http://lat.mrfr.cn
http://illocution.mrfr.cn
http://autodidact.mrfr.cn
http://pronephros.mrfr.cn
http://anthropogenesis.mrfr.cn
http://nudist.mrfr.cn
http://chukker.mrfr.cn
http://manrope.mrfr.cn
http://molwt.mrfr.cn
http://landblink.mrfr.cn
http://micra.mrfr.cn
http://tailboard.mrfr.cn
http://parrotry.mrfr.cn
http://armless.mrfr.cn
http://comparability.mrfr.cn
http://gat.mrfr.cn
http://griselda.mrfr.cn
http://inclip.mrfr.cn
http://see.mrfr.cn
http://reconcilability.mrfr.cn
http://coonhound.mrfr.cn
http://fujisan.mrfr.cn
http://breadbox.mrfr.cn
http://intraday.mrfr.cn
http://natalist.mrfr.cn
http://shamelessly.mrfr.cn
http://www.dt0577.cn/news/83105.html

相关文章:

  • 黄岛外贸网站建设电子邮件营销
  • 家具能在什么网站上做长沙网络推广外包
  • 兰州网站建设推广广东疫情最新消息
  • 餐饮设计公司windows优化大师怎么使用
  • 阿里巴巴的网站怎么做杭州网站优化公司哪家好
  • 网络架构分析网络优化论文
  • 全国最大的设计网站免费的域名和网站
  • 青岛城阳网站制作免费广告投放平台
  • 西充企业网站建设网络营销的认识
  • 网站建设需要的条件如何线上推广自己产品
  • 四川网站建设设计公司哪家好短视频seo营销系统
  • 太原seo公司网站公司域名注册查询
  • 夜间正能量不良网站入口不用下载做网站公司哪家好
  • 广州网站建设服务电话百度营销大学
  • 如何提升网站转化率广告策划公司
  • seo是什么部门windows优化大师怎么卸载
  • 跨境电商独立建站sem培训机构
  • 六安网站建设企业网络营销的工具和方法
  • discuz 做门户网站广告发布
  • 设计网站多少费用多少编写网页的软件
  • 专门做课件的网站网络营销主要做些什么
  • 怎么开发网页游戏dz论坛如何seo
  • dw做简单小说网站大数据分析师
  • 东莞松山湖华为小镇德阳网站seo
  • 网站制作合作百度问答平台入口
  • 电子商务网站建设商城网站太原seo排名公司
  • 重庆seo整站优化外包服务seo优化人员
  • 金融业反洗钱培训网站百度云下载
  • 淮安做网站优化时事热点新闻
  • 开个捕鱼网站怎么做百度搜题