目录
- 一、创建型
- 单例模式
- 懒汉式
- 饿汉式
- 工厂模式(工厂方法和抽象工厂)
- 简单工厂模式
- 工厂方法
- 抽象工厂
- 建造者模式
- 原型模式
- 单例模式
- 二、结构型
- 代理模式
- 桥接模式
- 装饰器模式
- 适配器模式
- 门面模式(外观模式)
- 组合模式(部分整体模式)
- 享元模式
- 三、行为型
- 观察者模式(发布订阅模式)
- 模板模式
- 策略模式
- 责任链模式
- 迭代器模式
- 状态模式
- 访问者模式
- 备忘录模式
- 命令模式
- 使用trait
- 使用函数指针
- 使用Fn trait
- 解释器模式
- 中介模式
设计模式
设计模式(design pattern)是对软件设计中普遍存在的各种问题所提出的解决方案
- 寻找变化点,然后在变化点应用设计模式
- 重构获得模式(不应该为了模式而模式)
重构关键法
- 静态->动态
- 早绑定->晚绑定
- 继承->组合
- 编译时依赖->运行时依赖
- 紧耦合->松耦合
代码质量标准
可维护性(maintainability):开发人员能够轻松地理解、修改和调试代码,以适应需求的变化或修复错误
可读性(readability):可读性好的代码使用清晰的命名、适当的注释和良好的代码风格,使得其他开发人员能够快速理解代码的意图和功能
可扩展性(extensibility):可扩展的代码设计考虑到未来的需求变化,通过模块化、低耦合和高内聚的设计,使得新增功能或修改现有功能变得容易
灵活性(flexibility):通过配置、参数化或拓展点来适应不同的环境或需求变化,而无需对核心代码进行大规模的修改
简洁性(simplicity):具有清晰的逻辑结构,没有冗余的部分,并且遵循简单直接的设计原则
可复用性(reusability):具有通用性和模块化的设计,可以在不同的项目或场景中被多次使用,从而减少开发时间和资源
可测试性(testability):具有良好的模块划分和依赖管理,使得单元测试、集成测试和自动化测试更容易实施,可测试的代码有助于发现和修复潜在的问题,并提供更高的代码质量
六大设计原则
SOLID原则
- SRP(Single Responsibility Principle,单一职责原则) :一个类或者模块只负责完成一个职责(或者功能)。将功能分解为小而聚焦的组件,使得每个组件只负责特定的任务,从而提高代码的可维护性和可读性
- OCP(Open-Closed Principle,开放封闭原则) :软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。在添加新功能时,应该通过扩展现有代码而不是修改现有代码来实现
- LSP(Liskov Substitution Principle,里氏替换原则) :子类应该能够在不破坏程序正确性的前提下,替代父类在任何地方出现的实例。遵循里氏替换原则可以确保代码的稳定性和可靠性,并促进代码的重用性
- ISP(Interface Segregation Principle,接口隔离原则) :客户端不应该依赖它不需要的接口。将接口细分为更小、更具体的部分,以减少对不相关功能的依赖,可以减少代码的耦合性,提高灵活性和可维护性
- DIP(Dependency Inversion Principle,依赖倒置原则) :高层模块不应该依赖低层模块,它们都应该依赖于抽象。使用抽象(接口或抽象类)来定义模块之间的依赖关系,而不是依赖具体的实现细节。可以实现松耦合的设计,提高代码的可测试性和可扩展性
DRY原则(Don’t Repeat Yourself)
不要重复自己,不要写重复的代码
KISS原则(Keep It Simple and Stupid)
尽量保持简单
YAGNI原则(You Aren’t Gonna Need It)
你不会需要它,不要去设计当前用不到的功能;不要去编写当前用不到的代码
CRP原则(Composite Reuse Principle)
尽量使用对象组合而不是继承
虽然Rust没有继承的关键字,但可以在trait中定义默认方法实现继承;将trait作为struct的字段或struct实现多个trait可以实现组合
LOD法则(Law of Demeter)
一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易
23种设计模式分类
创建型
单例模式、工厂模式(工厂方法和抽象工厂)、建造者模式、原型模式
结构型
代理模式、桥接模式、装饰者模式、适配器模式、门面模式、组合模式、享元模式
行为型
观察者模式、模板模式、策略模式、职责链模式、迭代器模式、状态模式、访问者模式、备忘录模式、命令模式、解释器模式、中介模式
一、创建型
单例模式、工厂模式(工厂方法和抽象工厂)、建造者模式、原型模式
单例模式
确保一个对象只有一个实例
标准库实现懒汉式
use std::sync::{Once, Arc, Mutex};struct Singleton {value: i32,
}
impl Singleton {// 初始化唯一的实例fn new() -> Self {Singleton { value: 0 }}// 获取单例实例fn get_instance() -> Arc<Mutex<Singleton>> {static mut INSTANCE: Option<Arc<Mutex<Singleton>>> = None;static ONCE: Once = Once::new();unsafe {ONCE.call_once(|| {// 确保只初始化一次let singleton = Singleton::new();INSTANCE = Some(Arc::new(Mutex::new(singleton)));});INSTANCE.clone().unwrap()}}// 设置值fn set_value(&mut self, value: i32) {self.value = value;}// 获取值fn get_value(&self) -> i32 {self.value}
}fn main() {// 获取单例实例并设置值let singleton = Singleton::get_instance();{let mut s = singleton.lock().unwrap();s.set_value(42);}// 获取单例实例并获取值{let s = singleton.lock().unwrap();println!("Singleton value: {}", s.get_value());}
}
懒汉式
在第一次需要时才进行初始化
需要第三方库lazy_static = "1.5.0"
use std::sync::{Arc, Mutex};
use lazy_static::lazy_static;struct Singleton {value: i32,
}
impl Singleton {fn new() -> Self {Singleton { value: 0 }}fn get_instance() -> Arc<Mutex<Singleton>> {lazy_static! {// 惰性初始化全局静态变量 INSTANCE// Arc共享所有权static ref INSTANCE: Arc<Mutex<Singleton>> = Arc::new(Mutex::new(Singleton::new()));}Arc::clone(&INSTANCE)}fn set_value(&mut self, value: i32) {self.value = value;}fn get_value(&self) -> i32 {self.value}
}fn main() {// 获取单例实例并设置值let singleton = Singleton::get_instance();{let mut s = singleton.lock().unwrap();s.set_value(42);}// 获取单例实例并获取值{let s = singleton.lock().unwrap();println!("Singleton value: {}", s.get_value());}
}
饿汉式
在程序启动时就创建单例实例
需要第三方库once_cell = "1.19.0"
use std::sync::{Arc, Mutex};
use std::sync::OnceLock;struct Singleton {value: i32,
}
impl Singleton {fn new() -> Self {Singleton { value: 0 }}fn get_instance() -> Arc<Mutex<Singleton>> {// 在程序启动时即初始化static INSTANCE: OnceLock<Arc<Mutex<Singleton>>> = OnceLock::new();INSTANCE.get_or_init(|| Arc::new(Mutex::new(Singleton::new()))).clone()}fn set_value(&mut self, value: i32) {self.value = value;}fn get_value(&self) -> i32 {self.value}
}
fn main() {// 获取单例实例并设置值let singleton = Singleton::get_instance();{let mut s = singleton.lock().unwrap();s.set_value(42);}// 获取单例实例并获取值{let s = singleton.lock().unwrap();println!("Singleton value: {}", s.get_value());}
}
工厂模式(工厂方法和抽象工厂)
简单工厂模式
根据传入的参数决定创建哪种类型的对象
// 产品trait
trait Product {fn use_product(&self);
}// 具体产品A
struct ConcreteProductA;
impl Product for ConcreteProductA {fn use_product(&self) {println!("Using ConcreteProductA");}
}// 具体产品B
struct ConcreteProductB;
impl Product for ConcreteProductB {fn use_product(&self) {println!("Using ConcreteProductB");}
}// 简单工厂
struct SimpleFactory;
impl SimpleFactory {fn create_product(product_type: &str) -> Box<dyn Product> {match product_type {"A" => Box::new(ConcreteProductA),"B" => Box::new(ConcreteProductB),_ => panic!("Unknown product type"),}}
}
fn main() {// 使用简单工厂创建产品Alet product_a = SimpleFactory::create_product("A");product_a.use_product();// 使用简单工厂创建产品Blet product_b = SimpleFactory::create_product("B");product_b.use_product();
}
工厂方法
定义创建对象的接口,将创建对象延迟到具体产品实现
// 产品trait
trait Product {fn use_product(&self);
}// 具体产品A
struct ConcreteProductA;
impl Product for ConcreteProductA {fn use_product(&self) {println!("Using ConcreteProductA");}
}// 具体产品B
struct ConcreteProductB;
impl Product for ConcreteProductB {fn use_product(&self) {println!("Using ConcreteProductB");}
}// 工厂接口
trait Factory {fn create_product(&self) -> Box<dyn Product>;
}// 具体工厂A
struct ConcreteFactoryA;
impl Factory for ConcreteFactoryA {fn create_product(&self) -> Box<dyn Product> {Box::new(ConcreteProductA)}
}// 具体工厂B
struct ConcreteFactoryB;
impl Factory for ConcreteFactoryB {fn create_product(&self) -> Box<dyn Product> {Box::new(ConcreteProductB)}
}fn main() {let factory_a: Box<dyn Factory> = Box::new(ConcreteFactoryA);let product_a = factory_a.create_product();product_a.use_product();let factory_b: Box<dyn Factory> = Box::new(ConcreteFactoryB);let product_b = factory_b.create_product();product_b.use_product();
}
抽象工厂
创建一系列trait,通过trait创建相关依赖的对象
- 需要在不同条件下创建实例时使用
// 抽象产品
trait AbstractProductA {fn feature_a(&self);
}
trait AbstractProductB {fn feature_b(&self);
}// 具体产品
struct ConcreteProductA1;
struct ConcreteProductA2;
struct ConcreteProductB1;
struct ConcreteProductB2;impl AbstractProductA for ConcreteProductA1 {fn feature_a(&self) {println!("Feature A1");}
}impl AbstractProductA for ConcreteProductA2 {fn feature_a(&self) {println!("Feature A2");}
}impl AbstractProductB for ConcreteProductB1 {fn feature_b(&self) {println!("Feature B1");}
}impl AbstractProductB for ConcreteProductB2 {fn feature_b(&self) {println!("Feature B2");}
}// 抽象工厂
trait AbstractFactory {fn create_product_a(&self) -> Box<dyn AbstractProductA>;fn create_product_b(&self) -> Box<dyn AbstractProductB>;
}// 具体工厂
struct ConcreteFactory1;
impl AbstractFactory for ConcreteFactory1 {fn create_product_a(&self) -> Box<dyn AbstractProductA> {Box::new(ConcreteProductA1)}fn create_product_b(&self) -> Box<dyn AbstractProductB> {Box::new(ConcreteProductB1)}
}struct ConcreteFactory2;
impl AbstractFactory for ConcreteFactory2 {fn create_product_a(&self) -> Box<dyn AbstractProductA> {Box::new(ConcreteProductA2)}fn create_product_b(&self) -> Box<dyn AbstractProductB> {Box::new(ConcreteProductB2)}
}fn main() {let factory1: Box<dyn AbstractFactory> = Box::new(ConcreteFactory1);let product_a1 = factory1.create_product_a();let product_b1 = factory1.create_product_b();product_a1.feature_a();product_b1.feature_b();let factory2: Box<dyn AbstractFactory> = Box::new(ConcreteFactory2);let product_a2 = factory2.create_product_a();let product_b2 = factory2.create_product_b();product_a2.feature_a();product_b2.feature_b();
}
建造者模式
将一个复杂对象的构建过程与其表示相分离,从而可以创建具有不同表示形式的对象
// 产品
struct Product {part_a: String,part_b: String,part_c: String,
}// 建造者接口
trait Builder {fn build_part_a(&mut self);fn build_part_b(&mut self);fn build_part_c(&mut self);fn get_result(&self) -> ∏
}// 具体建造者
struct ConcreteBuilder {product: Product,
}
impl ConcreteBuilder {fn new() -> Self {ConcreteBuilder {product: Product {part_a: String::new(),part_b: String::new(),part_c: String::new(),},}}
}impl Builder for ConcreteBuilder {fn build_part_a(&mut self) {self.product.part_a = String::from("Part A");}fn build_part_b(&mut self) {self.product.part_b = String::from("Part B");}fn build_part_c(&mut self) {self.product.part_c = String::from("Part C");}fn get_result(&self) -> &Product {&self.product}
}// 指挥者
struct Director;
impl Director {fn construct(builder: &mut dyn Builder) {builder.build_part_a();builder.build_part_b();builder.build_part_c();}
}
fn main() {let mut builder = ConcreteBuilder::new();Director::construct(&mut builder);let product = builder.get_result();println!("Product: {}, {}, {}", product.part_a, product.part_b, product.part_c);
}
原型模式
通过复制现有对象来创建新对象,而不是通过实例化类来创建对象
#[derive(Clone)]
struct Prototype {field: String,
}
impl Prototype {fn new(field: &str) -> Self {Prototype {field: field.to_string(),}}fn get_field(&self) -> &str {&self.field}
}
fn main() {let original = Prototype::new("Original");let clone = original.clone();println!("Original: {}", original.get_field());println!("Clone: {}", clone.get_field());
}
二、结构型
代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式
代理模式
通过代理中间层来访问真正的对象
// 被代理的对象
struct RealSubject;impl RealSubject {fn request(&self) {println!("RealSubject: Handling request.");}
}// 代理对象
struct Proxy {real_subject: RealSubject,
}impl Proxy {fn new() -> Self {Proxy {real_subject: RealSubject,}}fn request(&self) {println!("Proxy: Before calling RealSubject.");self.real_subject.request();println!("Proxy: After calling RealSubject.");}
}fn main() {let proxy = Proxy::new();proxy.request();
}
桥接模式
将抽象与实现解耦,使其独立变化
// 将抽象和实现连接起来
trait Implementor {fn operation_impl(&self) -> String;
}// 具体实现
struct ConcreteImplementorA;impl Implementor for ConcreteImplementorA {fn operation_impl(&self) -> String {"ConcreteImplementorA".to_string()}
}
// 具体实现
struct ConcreteImplementorB;impl Implementor for ConcreteImplementorB {fn operation_impl(&self) -> String {"ConcreteImplementorB".to_string()}
}// 抽象部分
struct Abstraction<I: Implementor> {implementor: I,
}impl<I: Implementor> Abstraction<I> {fn new(implementor: I) -> Self {Abstraction { implementor }}fn operation(&self) -> String {format!("Abstraction({})", self.implementor.operation_impl())}
}fn main() {let implementor_a = ConcreteImplementorA;let implementor_b = ConcreteImplementorB;let abstraction_a = Abstraction::new(implementor_a);let abstraction_b = Abstraction::new(implementor_b);println!("{}", abstraction_a.operation());println!("{}", abstraction_b.operation());
}
装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变其结构
// 定义一个 trait,表示基本的组件
trait Component {fn operation(&self) -> String;
}
// 具体组件实现
struct ConcreteComponent;
impl Component for ConcreteComponent {fn operation(&self) -> String {"ConcreteComponent".to_string()}
}
// 装饰器结构体
struct Decorator<T: Component> {component: T,
}
impl<T: Component> Component for Decorator<T> {fn operation(&self) -> String {// 在这里可以添加装饰器的功能format!("Decorator({})", self.component.operation())}
}
// 具体装饰器
struct ConcreteDecoratorA<T: Component> {component: T,
}
impl<T: Component> Component for ConcreteDecoratorA<T> {fn operation(&self) -> String {// 在装饰器中添加额外的行为format!("ConcreteDecoratorA({})", self.component.operation())}
}
fn main() {let component = ConcreteComponent;let decorated_component = Decorator { component };// 装饰功能let final_decorated = ConcreteDecoratorA { component: decorated_component };println!("{}", final_decorated.operation());
}
适配器模式
将一个接口转换为客户端所期望的接口,以便使得不兼容的接口能够一起工作
// 目标接口
trait Target {fn request(&self);
}// 适配者
struct Adaptee;impl Adaptee {fn specific_request(&self) {println!("Adaptee: Specific request.");}
}// 适配器
struct Adapter {adaptee: Adaptee,
}impl Target for Adapter {fn request(&self) {println!("Adapter: Adapting request.");// 适配self.adaptee.specific_request();}
}fn main() {let adaptee = Adaptee;let adapter = Adapter { adaptee };// 通过适配器调用适配者的方法adapter.request();
}
门面模式(外观模式)
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口
struct SubsystemA;impl SubsystemA {fn operation_a(&self) {println!("SubsystemA: Operation A.");}
}struct SubsystemB;impl SubsystemB {fn operation_b(&self) {println!("SubsystemB: Operation B.");}
}// 门面
struct Facade {subsystem_a: SubsystemA,subsystem_b: SubsystemB,
}impl Facade {fn new() -> Self {Facade {subsystem_a: SubsystemA,subsystem_b: SubsystemB,}}fn operation(&self) {println!("Facade: Coordinating operations.");self.subsystem_a.operation_a();self.subsystem_b.operation_b();}
}fn main() {let facade = Facade::new();facade.operation();
}
组合模式(部分整体模式)
把一组相似的对象当作一个单一的对象,将对象组合成树形结构,以表示部分和整体的层次关系
trait Component {fn operation(&self) -> String;
}
// 部分
struct Leaf {name: String,
}impl Component for Leaf {fn operation(&self) -> String {format!("Leaf: {}", self.name)}
}
// 组合
struct Composite {children: Vec<Box<dyn Component>>,
}impl Component for Composite {fn operation(&self) -> String {let mut result = "Composite:\n".to_string();for child in &self.children {result += &format!(" {}\n", child.operation());}result}
}fn main() {let leaf1 = Leaf { name: "Leaf1".to_string() };let leaf2 = Leaf { name: "Leaf2".to_string() };let mut composite = Composite { children: vec![] };composite.children.push(Box::new(leaf1));composite.children.push(Box::new(leaf2));println!("{}", composite.operation());
}
享元模式
通过共享对象来减少内存使用
use std::collections::HashMap;
// 享元对象
struct Flyweight {intrinsic_state: String,
}impl Flyweight {fn new(intrinsic_state: String) -> Self {Flyweight { intrinsic_state }}fn operation(&self, extrinsic_state: &str) {println!("Flyweight: {} - {}", self.intrinsic_state, extrinsic_state);}
}
// 享元工厂
struct FlyweightFactory {flyweights: HashMap<String, Flyweight>,
}impl FlyweightFactory {fn new() -> Self {FlyweightFactory { flyweights: HashMap::new() }}fn get_flyweight(&mut self, key: &str) -> &Flyweight {self.flyweights.entry(key.to_string()).or_insert_with(|| Flyweight::new(key.to_string()))}
}fn main() {let mut factory = FlyweightFactory::new();let flyweight1 = factory.get_flyweight("A");flyweight1.operation("First call");let flyweight2 = factory.get_flyweight("A");flyweight2.operation("Second call");
}
三、行为型
观察者模式、模板模式、责任链模式、迭代器模式、状态模式、访问者模式、备忘录模式、命令模式、解释器模式、中介模式
观察者模式(发布订阅模式)
一个对象的状态发生改变,所有的依赖对象都将得到通知
use std::collections::HashMap;#[derive(Default)]
pub struct Editor {publisher: Publisher,file_path: String,
}impl Editor {pub fn events(&mut self) -> &mut Publisher {&mut self.publisher}pub fn load(&mut self, path: String) {self.file_path = path.clone();self.publisher.notify(Event::Load, path);}pub fn save(&self) {self.publisher.notify(Event::Save, self.file_path.clone());}
}
#[derive(PartialEq, Eq, Hash, Clone)]
pub enum Event {Load,Save,
}// 订阅者
pub type Subscriber = fn(file_path: String);// 发布者发布事件
#[derive(Default)]
pub struct Publisher {events: HashMap<Event, Vec<Subscriber>>,
}impl Publisher {pub fn subscribe(&mut self, event_type: Event, listener: Subscriber) {self.events.entry(event_type.clone()).or_default();self.events.get_mut(&event_type).unwrap().push(listener);}pub fn unsubscribe(&mut self, event_type: Event, listener: Subscriber) {self.events.get_mut(&event_type).unwrap().retain(|&x| x != listener);}pub fn notify(&self, event_type: Event, file_path: String) {let listeners = self.events.get(&event_type).unwrap();for listener in listeners {listener(file_path.clone());}}
}
fn main() {let mut editor = Editor::default();editor.events().subscribe(Event::Load, |file_path| {let log = "/path/to/log/file.txt".to_string();println!("Save log to {}: Load file {}", log, file_path);});editor.events().subscribe(Event::Save, save_listener);editor.load("test1.txt".into());editor.load("test2.txt".into());editor.save();editor.events().unsubscribe(Event::Save, save_listener);editor.save();
}
// 具体订阅者
fn save_listener(file_path: String) {let email = "admin@example.com".to_string();println!("Email to {}: Save file {}", email, file_path);
}
模板模式
定义执行的稳定模板,将步骤延迟到实现
trait Template {fn step1(&self);// 变化的部分fn step2(&self);fn step3(&self);// 延迟到实现fn template_method(&self) {// 稳定的部分self.step1();self.step2();self.step3();}
}struct ConcreteImplementation1 {// 可以包含特定于这个实现的状态
}impl Template for ConcreteImplementation1 {fn step1(&self) {println!("ConcreteImplementation1: Step 1");}fn step2(&self) {println!("ConcreteImplementation1: Step 2");}fn step3(&self) {println!("ConcreteImplementation1: Step 3");}
}struct ConcreteImplementation2 {// 可以包含特定于这个实现的状态
}impl Template for ConcreteImplementation2 {fn step1(&self) {println!("ConcreteImplementation2: Step 1");}fn step2(&self) {println!("ConcreteImplementation2: Step 2");}fn step3(&self) {println!("ConcreteImplementation2: Step 3");}
}fn main() {let implementation1 = ConcreteImplementation1 {};implementation1.template_method();let implementation2 = ConcreteImplementation2 {};implementation2.template_method();
}
策略模式
实现的行为和算法可以在运行时更改
trait Strategy {fn execute(&self);
}struct ConcreteStrategyA;
impl Strategy for ConcreteStrategyA {fn execute(&self) {println!("Executing strategy A");}
}struct ConcreteStrategyB;
impl Strategy for ConcreteStrategyB {fn execute(&self) {println!("Executing strategy B");}
}
// 维护对策略对象,将请求委派给具体策略对象
struct Context {strategy: Box<dyn Strategy>,
}
impl Context {fn new(strategy: Box<dyn Strategy>) -> Self {Context { strategy }}fn execute_strategy(&self) {self.strategy.execute();}
}fn main() {let strategy_a = Box::new(ConcreteStrategyA {});// 多态调用let context_a = Context::new(strategy_a);context_a.execute_strategy();let strategy_b = Box::new(ConcreteStrategyB {});// 多态调用let context_b = Context::new(strategy_b);context_b.execute_strategy();
}
计算税种案例
// 抽象策略
trait TaxCalculationStrategy {fn calculate_tax(&self, income: f64) -> f64;
}
struct USTaxStrategy;
// 美国税
impl TaxCalculationStrategy for USTaxStrategy {fn calculate_tax(&self, income: f64) -> f64 {// 假设美国的税收计算逻辑if income <= 10000.0 {return income * 0.1;} else {return income * 0.15;}}
}
struct ChinaTaxStrategy;
// 中国税
impl TaxCalculationStrategy for ChinaTaxStrategy {fn calculate_tax(&self, income: f64) -> f64 {// 假设中国的税收计算逻辑if income <= 5000.0 {return 0.0;} else if income <= 8000.0 {return (income - 5000.0) * 0.03;} else {return income * 0.1;}}
}
struct JapanTaxStrategy;
// 日本税
impl TaxCalculationStrategy for JapanTaxStrategy {fn calculate_tax(&self, income: f64) -> f64 {// 假设日本的税收计算逻辑if income <= 20000.0 {return income * 0.05;} else {return income * 0.1;}}
}
// 上下文,稳定的部分
struct TaxCalculator {strategy: Box<dyn TaxCalculationStrategy>,
}
impl TaxCalculator {fn new(strategy: Box<dyn TaxCalculationStrategy>) -> Self {TaxCalculator { strategy }}fn calculate_tax(&self, income: f64) -> f64 {self.strategy.calculate_tax(income)}
}fn main() {let us_calculator = TaxCalculator::new(Box::new(USTaxStrategy {}));let china_calculator = TaxCalculator::new(Box::new(ChinaTaxStrategy {}));let japan_calculator = TaxCalculator::new(Box::new(JapanTaxStrategy {}));let income = 15000.0;// 多态调用println!("US tax for income {}: {}", income, us_calculator.calculate_tax(income));println!("China tax for income {}: {}", income, china_calculator.calculate_tax(income));println!("Japan tax for income {}: {}", income, japan_calculator.calculate_tax(income));
}
责任链模式
为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦
#[derive(Default)]
pub struct Patient {pub name: String,pub registration_done: bool,pub doctor_check_up_done: bool,pub medicine_done: bool,pub payment_done: bool,
}
// 部门公共方法
trait Department {fn execute(&mut self, patient: &mut Patient) {self.handle(patient);if let Some(next) = self.next() {next.execute(patient);}}fn handle(&mut self, patient: &mut Patient);fn next(&mut self) -> Option<&mut Box<dyn Department>>;
}
// 收银
#[derive(Default)]
struct Cashier {next: Option<Box<dyn Department>>,
}impl Department for Cashier {fn handle(&mut self, patient: &mut Patient) {if patient.payment_done {println!("付款完成 {}", patient.name);} else {println!("付款中{}", patient.name);patient.payment_done = true;}}fn next(&mut self) -> Option<&mut Box<dyn Department>> {self.next.as_mut()}
}
// 医生
struct Doctor {next: Option<Box<dyn Department>>,
}impl Doctor {pub fn new(next: Option<Box<dyn Department>>) -> Self {Self { next }}
}impl Department for Doctor {fn handle(&mut self, patient: &mut Patient) {if patient.doctor_check_up_done {println!("检查完成 {}", patient.name);} else {println!("检查中 {}", patient.name);patient.doctor_check_up_done = true;}}fn next(&mut self) -> Option<&mut Box<dyn Department>> {self.next.as_mut()}
}
// 药房
struct Medical {next: Option<Box<dyn Department>>,
}impl Medical {pub fn new(next: Option<Box<dyn Department>>) -> Self {Self { next }}
}impl Department for Medical {fn handle(&mut self, patient: &mut Patient) {if patient.medicine_done {println!("取药完成 {}", patient.name);} else {println!("取药中 {}", patient.name);patient.medicine_done = true;}}fn next(&mut self) -> Option<&mut Box<dyn Department>> {self.next.as_mut()}
}
// 门诊
struct Reception {next: Option<Box<dyn Department>>,
}impl Reception {pub fn new(next: Option<Box<dyn Department>>) -> Self {Self { next }}
}impl Department for Reception {fn handle(&mut self, patient: &mut Patient) {if patient.registration_done {println!("挂号完成 {}", patient.name);} else {println!("挂号 {}", patient.name);patient.registration_done = true;}}fn next(&mut self) -> Option<&mut Box<dyn Department>> {self.next.as_mut()}
}fn main() {let cashier = Box::new(Cashier::default());// 取药后收银let medical = Box::new(Medical::new(Some(cashier)));// 医生检查后取药let doctor = Box::new(Doctor::new(Some(medical)));// 挂号后医生检查let mut reception = Reception::new(Some(doctor));let mut patient = Patient {name: "张三".into(),..Patient::default()};reception.execute(&mut patient);println!("\n看病处理:\n");reception.execute(&mut patient);
}
迭代器模式
提供顺序访问元素的方式
struct Iterator {index: usize,data: Vec<i32>,
}impl Iterator {fn new(data: Vec<i32>) -> Self {Iterator { index: 0, data }}fn next(&mut self) -> Option<i32> {if self.index < self.data.len() {let value = self.data[self.index];self.index += 1;Some(value)} else {None}}
}
fn main() {let data = vec![1, 2, 3, 4];let mut iterator = Iterator::new(data);while let Some(value) = iterator.next() {println!("{}", value);}
}
状态模式
对象的行为基于状态改变
trait State {fn handle(&self);
}struct Context {state: Box<dyn State>,
}
impl Context {fn new(state: Box<dyn State>) -> Self {Context { state }}fn set_state(&mut self, state: Box<dyn State>) {self.state = state;}fn request(&self) {self.state.handle();}
}struct ConcreteStateA;
impl State for ConcreteStateA {fn handle(&self) {println!("Handling State A");}
}struct ConcreteStateB;
impl State for ConcreteStateB {fn handle(&self) {println!("Handling State B");}
}
struct ConcreteStateC;
impl State for ConcreteStateC {fn handle(&self) {println!("Handling State C");}
}
fn main() {let mut context = Context::new(Box::new(ConcreteStateA));context.request();// 切换状态context.set_state(Box::new(ConcreteStateB));context.request();// 切换状态context.set_state(Box::new(ConcreteStateC));context.request();
}
访问者模式
在不改变元素类的情况下定义新的操作,元素对象接收访问者对象,访问者就可以处理元素对象上的操作
trait Visitor {fn visit_element_a(&self, element: &ElementA);fn visit_element_b(&self, element: &ElementB);
}trait Element {fn accept(&self, visitor: &dyn Visitor);
}struct ElementA;
impl Element for ElementA {fn accept(&self, visitor: &dyn Visitor) {visitor.visit_element_a(self);}
}struct ElementB;
impl Element for ElementB {fn accept(&self, visitor: &dyn Visitor) {visitor.visit_element_b(self);}
}
// 具体访问者
struct ConcreteVisitor;
// 添加额外的功能
impl Visitor for ConcreteVisitor {fn visit_element_a(&self, _element: &ElementA) {println!("Visiting Element A");}fn visit_element_b(&self, _element: &ElementB) {println!("Visiting Element B");}
}fn main() {let element_a = ElementA;let element_b = ElementB;let visitor = ConcreteVisitor;// 接收访问者对象element_a.accept(&visitor);element_b.accept(&visitor);
}
备忘录模式
保存对象的状态,以便后续恢复
#[derive(Clone)]
// 备忘录
struct Memento {state: String,
}
// 发起者
struct Originator {state: String,
}impl Originator {fn new(state: String) -> Self {Originator { state }}// 存储状态fn create_memento(&self) -> Memento {Memento { state: self.state.clone() }}// 恢复状态fn restore(&mut self, memento: Memento) {self.state = memento.state;}
}fn main() {let mut originator = Originator::new("State1".to_string());let memento = originator.create_memento();originator.restore(memento);println!("Restored state: {}", originator.state);
}
命令模式
将请求封装成对象,从而允许参数化客户和请求
trait Command {fn execute(&mut self);
}
// 接收者
struct Light {is_on: bool,
}
impl Light {// 执行关灯命令fn toggle(&mut self) {self.is_on =!self.is_on;println!("Light is now {}", if self.is_on { "ON" } else { "OFF" });}
}
// 调用者
struct ToggleCommand<'a> {light: &'a mut Light,
}
impl<'a> Command for ToggleCommand<'a> {//发送命令fn execute(&mut self) {self.light.toggle();}
}fn main() {let mut light = Light { is_on: false };let mut command = ToggleCommand { light: &mut light };command.execute();let mut command = ToggleCommand { light: &mut light }; command.execute();
}
以下数据库迁移的例子,创建了两个命令实例,执行和回滚的方法
使用trait
fn main(){let mut schema = Schema::new();// 建表动作let cmd = Box::new(CreateTable);schema.add_migration(cmd);// 添加字段动作let cmd = Box::new(AddField);schema.add_migration(cmd);assert_eq!(vec!["create table","add field"],schema.execute());assert_eq!(vec!["remove field","drop table"],schema.rollback());
}
// 定义trait封装两个方法,所有实现了这个迁移trait的必须实现这两个方法
pub trait Migration{fn execute(&self)->&str;fn rollback(&self)->&str;
}
// 定义创建表的结构体并实现Migration这个trait
pub struct CreateTable;
impl Migration for CreateTable{fn execute(&self)->&str{"create table"}fn rollback(&self)->&str{"drop table"}
}
// 定义添加字段的结构体并实现Migration这个trait
pub struct AddField;
impl Migration for AddField{fn execute(&self)->&str{"add field"}fn rollback(&self)->&str {"remove field"}
}
// 定义操作的命令并实现
struct Schema{commands:Vec<Box<dyn Migration>>,
}
impl Schema{// 接受新命令fn new()->Self{Self{commands:vec![]}}fn execute(&self)->Vec<&str>{self.commands.iter().map(|cmd|cmd.execute()).collect()}fn rollback(&self)->Vec<&str>{self.commands.iter()// 遍历.rev()// 反转.map(|cmd|cmd.rollback())// 对每个命令迭代.collect()// 将操作后的元素搜集为新的Vec}fn add_migration(&mut self,cmd:Box<dyn Migration>){self.commands.push(cmd);}
}
使用函数指针
fn main(){let mut schema = Schema::new();// 使用闭包schema.add_migration(||"create table".to_string(),||"drop table".to_string());// 使用函数schema.add_migration(add_field,remove_field);// 使用命令assert_eq!(vec!["create table","add field"],schema.execute());assert_eq!(vec!["remove field","drop table"],schema.rollback());
}
//
type FnPtr=fn()->String;
// 定义命令
struct Command{execute:FnPtr,rollback:FnPtr,
}
// 存储迁移命令
struct Schema{commands:Vec<Command>,
}
impl Schema{fn new()->Self{Self { commands: vec![] }}fn add_migration(&mut self,execute:FnPtr,rollback:FnPtr){self.commands.push(Command{execute,rollback});}fn execute(&self)->Vec<String>{self.commands.iter().map(|cmd|(cmd.execute)()).collect()}fn rollback(&self)->Vec<String>{self.commands.iter().rev().map(|cmd|(cmd.rollback)()).collect()}
}fn add_field()->String{"add field".to_string()
}
fn remove_field()->String{"remove field".to_string()
}
使用Fn trait
动态派发
Fn可以多次不可变调用闭包
fn main(){let mut schema = Schema::new();// 使用闭包schema.add_migration(||"create table".to_string(),||"drop table".to_string());// 使用函数schema.add_migration(add_field,remove_field);// 使用命令assert_eq!(vec!["create table","add field"],schema.execute());assert_eq!(vec!["remove field","drop table"],schema.rollback());
}
//
type FnPtr=fn()->String;
// 定义命令
struct Command{execute:FnPtr,rollback:FnPtr,
}
// 存储迁移命令
struct Schema{commands:Vec<Command>,
}
impl Schema{fn new()->Self{Self { commands: vec![] }}fn add_migration(&mut self,execute:FnPtr,rollback:FnPtr){self.commands.push(Command{execute,rollback});}fn execute(&self)->Vec<String>{self.commands.iter().map(|cmd|(cmd.execute)()).collect()}fn rollback(&self)->Vec<String>{self.commands.iter().rev().map(|cmd|(cmd.rollback)()).collect()}
}fn add_field()->String{"add field".to_string()
}
fn remove_field()->String{"remove field".to_string()
}
解释器模式
定义一种语言的文法,并提供解释器来解释句子
// 抽象表达式
trait Expression {fn interpret(&self, context: &mut Context) -> i32;
}
// 具体表达式
struct Number {value: i32,
}
impl Expression for Number {fn interpret(&self, _context: &mut Context) -> i32 {self.value}
}
// 具体表达式
struct AddExpression {left: Box<dyn Expression>,right: Box<dyn Expression>,
}
impl Expression for AddExpression {fn interpret(&self, context: &mut Context) -> i32 {self.left.interpret(context) + self.right.interpret(context)}
}
// 具体表达式
struct SubtractExpression {left: Box<dyn Expression>,right: Box<dyn Expression>,
}
impl Expression for SubtractExpression {fn interpret(&self, context: &mut Context) -> i32 {self.left.interpret(context) - self.right.interpret(context)}
}struct Context {// 可以存储解释过程中的中间结果或其他上下文信息
}
fn main() {let mut context = Context {};let expression = AddExpression {left: Box::new(Number { value: 5 }),right: Box::new(SubtractExpression {left: Box::new(Number { value: 8 }),right: Box::new(Number { value: 3 }),}),};let result = expression.interpret(&mut context);println!("Result: {}", result);
}
中介模式
定义一个中介对象以封装一组对象之间的交互
use std::cell::RefCell;
use std::rc::Rc;// 定义中介者接口
trait Mediator {fn notify(&self, sender: &str, event: &str);
}// 定义组件结构
struct ComponentA {mediator: Rc<RefCell<dyn Mediator>>,
}
impl ComponentA {fn new(mediator: Rc<RefCell<dyn Mediator>>) -> Self {ComponentA { mediator }}fn do_something(&self) {println!("组件A做事");self.mediator.borrow().notify("ComponentA", "EventA");}
}struct ComponentB {mediator: Rc<RefCell<dyn Mediator>>,
}
impl ComponentB {fn new(mediator: Rc<RefCell<dyn Mediator>>) -> Self {ComponentB { mediator }}fn do_something_else(&self) {println!("组件B做事");self.mediator.borrow().notify("ComponentB", "EventB");}
}// 定义具体的中介者
struct ConcreteMediator {component_a: Option<Rc<ComponentA>>,component_b: Option<Rc<ComponentB>>,
}
impl ConcreteMediator {fn new() -> Self {ConcreteMediator {component_a: None,component_b: None,}}fn set_component_a(&mut self, component_a: Rc<ComponentA>) {self.component_a = Some(component_a);}fn set_component_b(&mut self, component_b: Rc<ComponentB>) {self.component_b = Some(component_b);}
}
// 实现中介者trait
impl Mediator for ConcreteMediator {fn notify(&self, sender: &str, event: &str) {match sender {"ComponentA" => {println!("中介者响应组件A事件: {}", event);if let Some(ref component_b) = self.component_b {component_b.do_something_else();}}"ComponentB" => {println!("中介者响应组件B事件: {}", event);if let Some(ref component_a) = self.component_a {component_a.do_something();}}_ => {}}}
}
fn main() {// 创建中介者,并将其包装为 `Rc<RefCell<ConcreteMediator>>`let mediator = Rc::new(RefCell::new(ConcreteMediator::new()));// 创建组件let component_a = Rc::new(ComponentA::new(Rc::clone(&mediator) as Rc<RefCell<dyn Mediator>>));let component_b = Rc::new(ComponentB::new(Rc::clone(&mediator) as Rc<RefCell<dyn Mediator>>));// 将组件注册到中介者中mediator.borrow_mut().set_component_a(Rc::clone(&component_a));mediator.borrow_mut().set_component_b(Rc::clone(&component_b));// 使用组件component_a.do_something();component_b.do_something_else();
}