2

I'm looking for a way to implement the strategy pattern in Rust. I wish to implement something similar to this pseudo-code:

class StrategyBase {
    Data data;
    def abstract methodAWorkingOnData();
    def abstract methodBWorkingOnData();
}

class StrategyImplOne {
    def methodAWorkingOnData()
        ... method code ...

    def methodBWorkingOnData()
        ... method code ....
}

class StrategyImplTwo {
    def methodAWorkingOnData()
        ... method code ...

    def methodBWorkingOnData()
        ... method code ....
}

I expected I could have a structure with two traits bound with it, but I can't find a way to implement such a pattern.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Vicctor
  • 803
  • 6
  • 13

1 Answers1

10

Combining the definition of the strategy pattern and The Rust Programming Language chapter on Generic Types, Traits, and Lifetimes yields a straightforward result.

Create a trait that represents the common interface and implement the trait a number of times. Then hold a generic type that implements the trait:

struct Context<S> {
    strategy: S,
}

impl<S> Context<S>
where
    S: Strategy,
{
    fn do_things(&self) {
        println!("Common preamble");
        self.strategy.execute();
        println!("Common postamble");
    }
}

trait Strategy {
    fn execute(&self);
}

struct ConcreteStrategyA;

impl Strategy for ConcreteStrategyA {
    fn execute(&self) {
        println!("ConcreteStrategyA")
    }
}

struct ConcreteStrategyB;

impl Strategy for ConcreteStrategyB {
    fn execute(&self) {
        println!("ConcreteStrategyB")
    }
}

fn main() {
    let a = Context {
        strategy: ConcreteStrategyA,
    };
    a.do_things();

    println!("\n---\n");

    let b = Context {
        strategy: ConcreteStrategyB,
    };
    b.do_things();
}

You can use an enum instead of traits if all of your potential implementations are known at compile time.

You still have to contend with any normal Rust design decisions such as ownership, lifetimes, and mutability; none of that is unique.

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366