Rust设计模式

目录

设计模式

设计模式(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() {
    // 使用简单工厂创建产品A
    let product_a = SimpleFactory::create_product("A");
    product_a.use_product();

    // 使用简单工厂创建产品B
    let 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) -> &Product;
}

// 具体建造者
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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cci497

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值