rust-unofficial / patterns

A catalogue of Rust design patterns, anti-patterns and idioms
https://rust-unofficial.github.io/patterns/
Mozilla Public License 2.0
8.11k stars 375 forks source link

Generic type constructors #5

Open jdm opened 9 years ago

jdm commented 9 years ago

I don't have a good name for this, but it's a pattern that Servo uses to sever linear dependencies between crates.

Before: Crate A

pub struct FluxCapacitor;
impl FluxCapacitor {
    pub fn new() -> FluxCapacitor {
        FluxCapacitor
    }
}

Crate B

extern crate a;
pub fn instantiate_flux_capacitor() {
    let capacitor = a::FluxCapacitor::new();
    //...
}

Crate C

extern crate b;
fn start() {
    b::instantiate_flux_capacitor();
}

After: Crate A_Shared

pub trait FluxCapacitorCreator {
    fn create() -> Self;
}

Crate A

extern crate a_shared;
pub struct FluxCapacitor;
impl FluxCapacitor {
    fn new() -> FluxCapacitor {
        FluxCapacitor
    }
}
impl FluxCapacitorCreator for FluxCapacitor {
    fn create() -> FluxCapacitor {
        FluxCapacitor::new()
    }
}

Crate B

extern crate a_shared;
pub fn instantiate_flux_capacitor<T: a_shared::FluxCapacitorCreator>() {
    let capacitor = T::create();
    //...
}

Crate C

extern crate a;
extern crate b;
fn start() {
    b::instantiate_flux_capacitor::<FluxCapacitor>();
}