Rust设计模式
目录
- 一、创建型
- 单例模式
- 懒汉式
- 饿汉式
- 工厂模式(工厂方法和抽象工厂)
- 简单工厂模式
- 工厂方法
- 抽象工厂
- 建造者模式
- 原型模式
- 单例模式
- 二、结构型
- 代理模式
- 桥接模式
- 装饰器模式
- 适配器模式
- 门面模式(外观模式)
- 组合模式(部分整体模式)
- 享元模式
- 三、行为型
- 观察者模式(发布订阅模式)
- 模板模式
- 策略模式
- 责任链模式
- 迭代器模式
- 状态模式
- 访问者模式
- 备忘录模式
- 命令模式
- 使用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() {
// 使用简单工厂创建产品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) -> ∏
}
// 具体建造者
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();
}