Rust设计模式:从理论到实践
设计模式是软件开发中经过验证的常见问题解决方案。在Rust中,由于其独特的所有权(ownership)系统以及缺乏经典的面向对象编程,许多经典模式呈现出新的面貌。本文将介绍四种关键模式:Singleton、Factory、Builder和Strategy,并针对惯用的Rust进行适配。
1. Rust中的Singleton(单例模式)
Rust没有传统意义上的全局静态变量。然而,可以通过lazy_static或OnceCell实现Singleton。下面是一个使用std::sync::OnceLock(自Rust 1.70起可用)的示例。
使用OnceLock实现
use std::sync::OnceLock;
static CONFIG: OnceLock<Config> = OnceLock::new();
#[derive(Debug)]struct Config { db_url: String, port: u16,}
fn get_config() -> &'static Config { CONFIG.get_or_init(|| { Config { db_url: String::from("postgres://localhost"), port: 5432, } })}
fn main() { let cfg = get_config(); println!("{:?}", cfg);}关键点: OnceLock保证一次性初始化且线程安全。这是Rust中的惯用方式。
2. 通过trait实现Factory(工厂模式)
Rust中的Factory模式可以通过trait很好地实现。我们不需要抽象类——只需通过trait定义接口即可。
示例:创建交通工具
trait Transport { fn deliver(&self);}
struct Truck;impl Transport for Truck { fn deliver(&self) { println!("陆路卡车运输"); }}
struct Ship;impl Transport for Ship { fn deliver(&self) { println!("海路轮船运输"); }}
struct LogisticsFactory;
impl LogisticsFactory { fn create_transport(route_type: &str) -> Box<dyn Transport> { match route_type { "land" => Box::new(Truck), "sea" => Box::new(Ship), _ => panic!("未知的路线类型"), } }}
fn main() { let transport = LogisticsFactory::create_transport("sea"); transport.deliver();}优势: Rust不需要继承——多态通过trait和Box<dyn Trait>实现。
3. 带类型化链式调用的Builder(构建器模式)
Builder在Rust中被广泛使用,特别是对于具有多个可选参数的结构体。我们通过返回&mut Self的类型化方法链来实现它。
示例:创建HTTP请求
#[derive(Debug, Default)]struct HttpRequest { url: String, method: String, headers: Vec<(String, String)>, body: Option<String>,}
struct HttpRequestBuilder { request: HttpRequest,}
impl HttpRequestBuilder { fn new(url: &str) -> Self { HttpRequestBuilder { request: HttpRequest { url: url.to_string(), method: "GET".to_string(), ..Default::default() }, } }
fn method(&mut self, method: &str) -> &mut Self { self.request.method = method.to_string(); self }
fn header(&mut self, key: &str, value: &str) -> &mut Self { self.request.headers.push((key.to_string(), value.to_string())); self }
fn body(&mut self, body: &str) -> &mut Self { self.request.body = Some(body.to_string()); self }
fn build(&self) -> HttpRequest { // 此处可添加验证逻辑 HttpRequest { ..self.request.clone() } }}
fn ma