国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

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

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

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

17.3.1. 狀態(tài)模式

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

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

看個例子:

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

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

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

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

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

    • 即使我們調(diào)用了add_text并向帖子添加了一些內(nèi)容,我們?nèi)匀幌M?code>content方法返回一個空字符串切片,因為帖子仍處于草稿狀態(tài)。

    • request_review會提取出state字段下的狀態(tài),取出來之后,State就會暫時變?yōu)?code>None,因為所有權(quán)被移動出來了。這個時候調(diào)用state上的request_review方法來請求審批。
      stateDraft狀態(tài)時,就會調(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目前定義了兩個方法,只有簽名,沒有具體實現(xiàn):

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

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

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

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

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

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


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


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

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

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

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

對于DraftPendingReview來說默認實現(xiàn)就可以滿足需求了。只需要在Published中寫一個方法覆蓋默認實現(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>,為了解包必須寫一步錯誤處理,用unwrap即可。最后就調(diào)用content方法,根據(jù)所處的狀態(tài)不同,content的具體實現(xiàn)也會有所不同。

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

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

但它的缺點也比較明顯:

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

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

如果我們嚴格按照面向?qū)ο蟮哪J綄懏斎皇强尚械?#xff0c;但是發(fā)揮不出Rust的全部威力。

下面我們會結(jié)合Rust的特點來修改,具體來說就是把狀態(tài)和行為改為具體的類型。Rust類型檢查系統(tǒng)會通過編譯時錯誤來阻止用戶使用無效的狀態(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兩個結(jié)構(gòu)體,這兩者都有一個存儲String類型的content字段

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

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

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

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

這樣寫不會出現(xiàn)意外的情況,因為只有通過審批正式發(fā)布的狀態(tài)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. 總結(jié)

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

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

http://m.aloenet.com.cn/news/806.html

相關(guān)文章:

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