Rust語言之GoF設計模式:工廠模式
工廠模式的是將建立邏輯封裝在一個方法中,在 "外部"實現對其使用。
(banq::老子道德經中“無以為用”,“無”的意思就是跳出事物內部細節,從事物外部才能使用它。Rust的事物內部和外部邊界很嚴格,所有權概念使然。)
簡單工廠
簡單工廠模式只是一個帶有大條件的函式,根據引數選擇要例項化的產品,然後返回,因為沒有繼承和複雜的建立特徵,因此它是簡單工廠。
create_button是一個功能(一個事物):建立隨機按鈕:
fn create_button(random_number: f64) -> Box<dyn Button> { if random_number < 0.5 { Box::new(TitleButton::new("Button".to_string())) } else { Box::new(IdButton::new(123)) } } |
而render_dialog則使用從create_button得到的任何結果,再對其進行操作:
fn render_dialog(random_number: f64) { // ... let button = create_button(random_number); button.render(); // ... } |
工廠方法
工廠方法是一種建立設計模式,它提供了在超特徵中建立物件的介面,但允許子特徵改變將要建立的物件的型別。
案例一:以建立對話方塊按鈕為例:
主介面Dialog:gui.rs
pub trait Button { fn render(&self); fn on_click(&self); } /// Dialog有一個工廠方法`create_button`。 /// /// 它根據工廠的實現來建立不同的按鈕。 pub trait Dialog { /// 這裡是工廠方法,必須有一個具體的實現來覆蓋,具體實現有兩個。 fn create_button(&self) -> Box<dyn Button>; fn render(&self) { let button = self.create_button(); button.render(); } fn refresh(&self) { println!("Dialog - Refresh"); } } |
工廠方法的兩個實現之一:Windows風格的按鈕:windows_gui.rs
use crate::gui::{Button, Dialog}; pub struct WindowsButton; impl Button for WindowsButton { fn render(&self) { println!("Drawing a Windows button"); self.on_click(); } fn on_click(&self) { println!("Click! Hello, Windows!"); } } pub struct WindowsDialog; impl Dialog for WindowsDialog { /// 建立一個windows風格按鈕 fn create_button(&self) -> Box<dyn Button> { Box::new(WindowsButton) } } |
工廠方法的兩個實現之一:html_gui.rs
use crate::gui::{Button, Dialog}; pub struct HtmlButton; impl Button for HtmlButton { fn render(&self) { println!("<button>Test Button</button>"); self.on_click(); } fn on_click(&self) { println!("Click! Button says - 'Hello World!'"); } } pub struct HtmlDialog; impl Dialog for HtmlDialog { /// 建立一個 HTML 按鈕. fn create_button(&self) -> Box<dyn Button> { Box::new(HtmlButton) } } |
工廠方法的呼叫客戶端:main.rs
mod gui; mod html_gui; mod init; mod windows_gui; use init::initialize; fn main() { // 其餘的程式碼並不依賴於特定的對話方塊型別,因為 // 它透過抽象的`Dialog`特性與所有對話方塊物件一起工作。 // 在`gui`模組中定義的抽象的`Dialog`特性對所有的對話方塊都有效。 let dialog = initialize(); dialog.render(); dialog.refresh(); } |
案例二:遊戲案例:
遊戲房間主介面:game.rs
/// 將用工廠方法例項化的迷宮房間。 pub trait Room { fn render(&self); } /// 迷宮遊戲有一個工廠方法產生不同的房間。 pub trait MazeGame { type RoomImpl:Room; /// 一個工廠方法 fn rooms(&self) -> Vec<Self::RoomImpl>; fn play(&self) { for room in self.rooms() { room.render()。 } } } /// 客戶端程式碼初始化資源並做其他準備工作。 /// 然後它使用一個工廠來構建和執行遊戲。 pub fn run(maze_game:impl MazeGame) { println! ("載入資源...")。 println!("開始遊戲...")。 maze_game.play()。 } |
遊戲房間有兩個實現:
- 普通遊戲房間:ordinary_maze.rs
- 魔法遊戲房間:magic_maze.rs
呼叫工廠方法的客戶端程式碼:main.rs
mod game; mod magic_maze; mod ordinary_maze; use magic_maze::MagicMaze; use ordinary_maze::OrdinaryMaze; ///遊戲執行時,根據具體的工廠型別,會有不同的迷宮。 ///要麼是普通迷宮,要麼是魔法迷宮。 /// /// 為了演示的目的,兩種迷宮都用來構建遊戲。 fn main() { // 選項1:遊戲從一個普通迷宮開始。 let ordinary_maze = OrdinaryMaze::new(); game::run(ordinary_maze); // 選項2:遊戲從一個魔法迷宮開始。 let magic_maze = MagicMaze::new(); game::run(magic_maze); } |
相關文章
- Rust語言之GoF設計模式:抽象工廠模式RustGo設計模式抽象
- Rust語言之GoF設計模式:靜態工廠RustGo設計模式
- Rust語言之GoF設計模式: 模板方法模式RustGo設計模式
- Rust語言之GoF設計模式:原型模式RustGo設計模式原型
- Rust語言之GoF設計模式:迭代器模式RustGo設計模式
- Rust語言之GoF設計模式:Flyweight享元模式RustGo設計模式
- Rust語言之GoF設計模式:責任鏈模式RustGo設計模式
- Rust語言之GoF設計模式:中介者Mediator模式RustGo設計模式
- Rust語言之GoF設計模式:備忘錄Memento模式RustGo設計模式
- Rust語言之GoF設計模式: 直譯器Interpreter模式RustGo設計模式
- Rust語言之GoF設計模式:介面卡AdapterRustGo設計模式APT
- GoF之工廠模式Go模式
- 設計模式——簡單工廠(又叫靜態工廠方法,不屬於GOF23中設計模式)設計模式Go
- 設計模式-工廠模式二(工廠方法模式)設計模式
- 設計模式 —— 工廠模式設計模式
- 設計模式(工廠模式)設計模式
- 設計模式----工廠模式設計模式
- 【設計模式】工廠模式設計模式
- 設計模式-工廠模式設計模式
- 設計模式----工廠設計模式設計模式
- 設計模式-工廠設計模式設計模式
- 設計模式-簡單工廠、工廠方法模式、抽象工廠模式設計模式抽象
- C# 設計模式(1)——簡單工廠模式、工廠模式、抽象工廠模式C#設計模式抽象
- 設計模式學習(二)工廠模式——抽象工廠模式設計模式抽象
- 設計模式之工廠模式!深入解析簡單工廠模式,工廠方法模式和抽象工廠模式設計模式抽象
- 設計模式 - 工廠方法模式設計模式
- 設計模式 —— 抽象工廠模式設計模式抽象
- 設計模式-抽象工廠模式設計模式抽象
- Java 設計模式(工廠模式)Java設計模式
- PHP設計模式-- 工廠模式PHP設計模式
- 【設計模式】工廠方法模式設計模式
- 設計模式 #2 (工廠模式)設計模式
- java設計模式 – 工廠模式Java設計模式
- 設計模式~~~工廠方法模式設計模式
- 設計模式——抽象工廠模式設計模式抽象
- Java設計模式(工廠模式)Java設計模式
- Java設計模式-工廠模式Java設計模式
- 設計模式之【工廠模式】設計模式