中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站開發(fā)流程主要分成什么seo外鏈代發(fā)

網(wǎng)站開發(fā)流程主要分成什么,seo外鏈代發(fā),濟(jì)南網(wǎng)站公司哪家好,山東網(wǎng)站建設(shè)哪里好喜歡的話別忘了點(diǎn)贊、收藏加關(guān)注哦,對(duì)接下來的教程有興趣的可以關(guān)注專欄。謝謝喵!(・ω・) 17.3.1. 狀態(tài)模式 狀態(tài)模式(state pattern) 是一種面向?qū)ο笤O(shè)計(jì)模式,指的是一個(gè)值擁有的內(nèi)部狀態(tài)由數(shù)個(gè)狀態(tài)對(duì)象&#xff08…

喜歡的話別忘了點(diǎn)贊、收藏加關(guān)注哦,對(duì)接下來的教程有興趣的可以關(guān)注專欄。謝謝喵!(=・ω・=)
請(qǐng)?zhí)砑訄D片描述

17.3.1. 狀態(tài)模式

狀態(tài)模式(state pattern) 是一種面向?qū)ο笤O(shè)計(jì)模式,指的是一個(gè)值擁有的內(nèi)部狀態(tài)由數(shù)個(gè)狀態(tài)對(duì)象(state object) 表達(dá)而成,而值的行為隨著內(nèi)部狀態(tài)的改變而改變。

使用狀態(tài)模式意味著:業(yè)務(wù)需求變化時(shí),不需要修改持有狀態(tài)的值的代碼,或者是使用這個(gè)值的代碼;只需要更新狀態(tài)對(duì)象內(nèi)部的代碼,以改變其規(guī)則,或者是增加一些新的狀態(tài)對(duì)象。

看個(gè)例子:

博客文章一開始是一個(gè)空草稿。草稿完成后,要求對(duì)該帖子進(jìn)行審查。當(dāng)帖子獲得批準(zhǔn)后,就會(huì)發(fā)布。只有已發(fā)布的博客帖子才會(huì)返回要打印的內(nèi)容,因此不會(huì)意外發(fā)布未經(jīng)批準(zhǔn)的帖子。

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創(chuàng)建新的博客文章草稿。首先創(chuàng)建一個(gè)Post類型的實(shí)例,命名為post。它是可變的,因?yàn)樘幱诓莞鍫顟B(tài)的文章還可以修改
  • 然后通過Post上的add_text方法增加了"I ate a salad for lunch today"這句話
  • 接下來使用request_review方法請(qǐng)求審批
  • 最后使用approve方法獲得審批通過

PS:添加的assert_eq!在代碼中用于演示目的。單元測(cè)試可能包含斷言草稿博客文章從content方法返回一個(gè)空字符串,但我們不打算為此示例編寫測(cè)試。

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結(jié)構(gòu)體有兩個(gè)字段,一個(gè)字段是state,用于存儲(chǔ)文章當(dāng)下的狀態(tài),它一共有三種狀態(tài):草稿、等待審批和已發(fā)布。Box<dyn State>代表只要是實(shí)現(xiàn)了State trait的類型就可以存入
    通過這個(gè)字段,Post類型能在內(nèi)部管理狀態(tài)與狀態(tài)之間的變化,這個(gè)狀態(tài)的變化是通過用戶調(diào)用Post上的方法實(shí)現(xiàn)的,而用戶只能通過調(diào)用這些方法來改變值(因?yàn)?code>Post下的字段未設(shè)為公開,所以用戶沒辦法直接修改字段的值)。

  • 下文通過impl塊為Post實(shí)現(xiàn)了一些方法:

    • new函數(shù)用于創(chuàng)建一個(gè)Post類型的實(shí)例,其初始的content值是一個(gè)空的字符串;初始的state處于草稿狀態(tài),所以state存儲(chǔ)的是Draft結(jié)構(gòu)體(下文有講)

    • add_text會(huì)往content字段使用pusth_str方法來添加內(nèi)容

    • 即使我們調(diào)用了add_text并向帖子添加了一些內(nèi)容,我們?nèi)匀幌M?code>content方法返回一個(gè)空字符串切片,因?yàn)樘尤蕴幱诓莞鍫顟B(tài)。

    • request_review會(huì)提取出state字段下的狀態(tài),取出來之后,State就會(huì)暫時(shí)變?yōu)?code>None,因?yàn)樗袡?quán)被移動(dòng)出來了。這個(gè)時(shí)候調(diào)用state上的request_review方法來請(qǐng)求審批。
      當(dāng)stateDraft狀態(tài)時(shí),就會(huì)調(diào)用Draft結(jié)構(gòu)體上的request_review方法(下文有講),把state字段的值從Draft變?yōu)榱?code>PendingReview,把狀態(tài)更新回state上。

  • approve表示審批通過,其寫法跟request_review差不多,把狀態(tài)取出來,調(diào)用self上的approve方法來更新狀態(tài)。

  • State trait目前定義了兩個(gè)方法,只有簽名,沒有具體實(shí)現(xiàn):

    • request_review表示請(qǐng)求審批
    • approve表示審批通過
      PS:注意它的簽名的參數(shù)是Box<self>,與selfmut self有區(qū)別,Box<self>意味著它只能被包裹著當(dāng)前類型的Box實(shí)例,它會(huì)在調(diào)用過程中獲取Box(self)的所有權(quán),并使舊的實(shí)效,從而修改狀態(tài)。
  • Draft用于表示草稿狀態(tài),不需要實(shí)際的內(nèi)容,所以只要聲明一個(gè)沒有字段的結(jié)構(gòu)體即可

  • 通過impl塊為Draft實(shí)現(xiàn)了State trait:

    • request_review表示請(qǐng)求審批,把值變?yōu)榱?code>PendingReview。
    • approve表示審批通過。由于approve在此時(shí)沒用,只需要把本身傳回去即可,所以返回值是self。
  • PendingReviewing用于表示等待審批,不需要實(shí)際的內(nèi)容,所以只要聲明一個(gè)沒有字段的結(jié)構(gòu)體即可

  • 通過impl塊為PendingReview實(shí)現(xiàn)了State trait:

    • request_review表示請(qǐng)求審批,此時(shí)狀態(tài)不會(huì)變,只需要把本身傳回去即可,所以返回值是self
    • approve表示審批通過,返回Published結(jié)構(gòu)體。
  • Published用于表示已發(fā)表,不需要實(shí)際的內(nèi)容,所以只要聲明一個(gè)沒有字段的結(jié)構(gòu)體即可

  • 通過impl塊為Published實(shí)現(xiàn)了State trait。但是它都處于已發(fā)布的狀態(tài)了,所以request_reviewapprove都沒啥用,直接返回本身self就行。


我們?yōu)槭裁床皇褂妹杜e類型的變體作為帖子狀態(tài)?這當(dāng)然是一個(gè)可能的解決方案,但它的其缺點(diǎn)之一是使用枚舉是每個(gè)檢查枚舉值的地方都需要一個(gè)match表達(dá)式或類似的表達(dá)式來處理每個(gè)可能的變體。


這樣寫會(huì)存在很多重復(fù)的代碼,有些代碼根本沒用;但是它的優(yōu)點(diǎn)也很明顯:無論狀態(tài)值是什么Post上的request_review方法都不需要改變,每個(gè)狀態(tài)都負(fù)責(zé)自己的運(yùn)行規(guī)則。

這里還有content方法還需要修改,我們想要在發(fā)布狀態(tài)下使它可見,而其他兩種情況下看不到。一樣可以使用面向?qū)ο蟮脑O(shè)計(jì)模式。以下是原來的代碼:

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 {""}
}

寫了個(gè)默認(rèn)實(shí)現(xiàn),返回空字符串。注意這里要使用生命周期,因?yàn)榻邮盏氖?code>Post的引用,然后返回的可能是Post中某一部分的引用,所以返回值的生命周期和Post參數(shù)的生命周期是相關(guān)聯(lián)的。

對(duì)于DraftPendingReview來說默認(rèn)實(shí)現(xiàn)就可以滿足需求了。只需要在Published中寫一個(gè)方法覆蓋默認(rèn)實(shí)現(xiàn):

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里面值的引用,所以說調(diào)用了as_ref方法得到Option<&T>,為了解包必須寫一步錯(cuò)誤處理,用unwrap即可。最后就調(diào)用content方法,根據(jù)所處的狀態(tài)不同,content的具體實(shí)現(xiàn)也會(huì)有所不同。

17.3.2. 狀態(tài)模式的取舍權(quán)衡

狀態(tài)模式的優(yōu)點(diǎn)如上所見:無論狀態(tài)值是什么Post上的request_review方法都不需要改變,每個(gè)狀態(tài)都負(fù)責(zé)自己的運(yùn)行規(guī)則。

但它的缺點(diǎn)也比較明顯:

  • 需要重復(fù)實(shí)現(xiàn)一些邏輯代碼
  • 某些狀態(tài)之間是相互耦合的,如果我們新增一個(gè)狀態(tài),這時(shí)候跟它相關(guān)聯(lián)的代碼就需要修改

17.3.3. 將狀態(tài)和行為編碼為類型

如果我們嚴(yán)格按照面向?qū)ο蟮哪J綄懏?dāng)然是可行的,但是發(fā)揮不出Rust的全部威力。

下面我們會(huì)結(jié)合Rust的特點(diǎn)來修改,具體來說就是把狀態(tài)和行為改為具體的類型。Rust類型檢查系統(tǒng)會(huì)通過編譯時(shí)錯(cuò)誤來阻止用戶使用無效的狀態(tài)。

修改后的代碼如下:
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兩個(gè)結(jié)構(gòu)體,這兩者都有一個(gè)存儲(chǔ)String類型的content字段

  • 通過impl塊寫了Postnew方法和content方法:

    • new方法會(huì)創(chuàng)建一個(gè)空的DraftPost結(jié)構(gòu)體
    • content方法就會(huì)返回本身的content字段的值
  • 通過impl塊寫了DraftPost的方法:

    • add_text方法用于給DraftPostcontent添加文字
    • request_review方法用于請(qǐng)求審批,調(diào)用這個(gè)方法就會(huì)返回另一個(gè)狀態(tài)PendingReviewPost,表示正在審批中。這個(gè)狀態(tài)是在下文定義的
  • 聲明了PendingReviewPost結(jié)構(gòu)體,有一個(gè)存儲(chǔ)String類型的content字段。通過impl在它上面寫了一個(gè)approve方法用于通過審批

這里的Post就指正式發(fā)布之后的PostDraftPost就代表還處于草稿狀態(tài)的文章,PendingReviewPost表示正在審批的文章。審批成功就會(huì)把content的值返回到Postcontent字段里以供使用。

這樣寫不會(huì)出現(xiàn)意外的情況,因?yàn)橹挥型ㄟ^審批正式發(fā)布的狀態(tài)Post才有content方法來獲取文章。

此時(shí)的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. 總結(jié)

Rust不僅能夠?qū)崿F(xiàn)面向?qū)ο蟮脑O(shè)計(jì)模式,還可以支持更多的模式。例如將狀態(tài)和行為編碼為類型。

面對(duì)對(duì)象的經(jīng)典模式并不總是Rust編程實(shí)踐中的最佳選擇,因?yàn)镽ust具有其他面向?qū)ο笳Z言所沒有的所有權(quán)特性。

http://www.risenshineclean.com/news/806.html

相關(guān)文章:

  • 網(wǎng)站代理怎么做/成都seo正規(guī)優(yōu)化
  • 學(xué)網(wǎng)頁設(shè)計(jì)需要什么基礎(chǔ)/寧波優(yōu)化網(wǎng)站排名軟件
  • 廣東個(gè)人備案網(wǎng)站內(nèi)容/百度平臺(tái)推廣聯(lián)系方式
  • 01.線性代數(shù)是如何將復(fù)雜的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為可計(jì)算的數(shù)學(xué)問題,這個(gè)過程是如何進(jìn)行的
  • Cursor Pro取消500次請(qǐng)求限制,無限用的體驗(yàn)更好了嗎?
  • 武漢互聯(lián)網(wǎng)公司排行榜/成都seo顧問
  • 紹興做企業(yè)網(wǎng)站的公司/營銷策劃主要做些什么
  • sae wordpress sitemap/東莞seo建站公司
  • 武漢網(wǎng)站制作/建立一個(gè)網(wǎng)站的費(fèi)用
  • 黑河商城網(wǎng)站建設(shè)/東莞網(wǎng)絡(luò)推廣平臺(tái)
  • 蔚縣做網(wǎng)站/云資源軟文發(fā)布平臺(tái)
  • 小企業(yè)網(wǎng)站建設(shè)的大品牌/優(yōu)化整站
  • 網(wǎng)站開發(fā)管理/網(wǎng)站優(yōu)化員seo招聘
  • 慶陽網(wǎng)站設(shè)計(jì)/創(chuàng)建自己的網(wǎng)頁
  • 做系統(tǒng)下載網(wǎng)站建設(shè)/最新經(jīng)濟(jì)新聞
  • 工會(huì)網(wǎng)站平臺(tái)建設(shè)/推廣普通話的宣傳標(biāo)語
  • 做網(wǎng)站和做網(wǎng)頁一樣嗎/大數(shù)據(jù)查詢
  • 3d做號(hào)網(wǎng)站/刷推廣軟件
  • 網(wǎng)上購物系統(tǒng)源代碼/關(guān)鍵詞優(yōu)化建議
  • 北京 做網(wǎng)站/新站整站優(yōu)化
  • c語言在線編程網(wǎng)站/全自動(dòng)推廣軟件
  • 怎么網(wǎng)站代備案/微信推廣方式有哪些
  • 網(wǎng)站規(guī)劃的一般步驟/搭建一個(gè)網(wǎng)站平臺(tái)需要多少錢
  • 石家莊網(wǎng)站搭建/我的百度賬號(hào)登錄
  • 做網(wǎng)站怎么加彈幕/營銷咨詢公司
  • 網(wǎng)站建設(shè)中的功能/百度地址
  • 素材網(wǎng)站下載/口碑營銷的主要手段有哪些
  • 校友網(wǎng)站 建設(shè)/強(qiáng)力搜索引擎
  • 怎么做百度網(wǎng)站/怎么建立個(gè)人網(wǎng)站
  • wordpress 作者簡介/東莞網(wǎng)站優(yōu)化關(guān)鍵詞排名