Skip to content

Use rust's package manager and add strategy pattern #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ a.out
*.py[co]
_site/
build/
target/
40 changes: 0 additions & 40 deletions Makefile

This file was deleted.

12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ Using
-----

To learn about a given pattern, open up the source code. All of the patterns are
defined in the [patterns][patterns] directory.
defined in the [Rust sources](rust/src/) directory.

To run a given pattern, just run it like this:
To run a all the patterns, just run :

```bash

# Be in the repository
$ cd design-patterns/
$ cd rust/

# Run the Adapter pattern
$ make adapter
# Run all the patterns
$ cargo run

```

Expand All @@ -39,7 +39,7 @@ comes to software design.
Learning
--------

All of the patterns can be found in the [patterns][patterns] directory.
All of the patterns can be found in the [Rust sources](rust/src/) directory.

To learn about a given pattern, just navigate to the [documentation][docs] page for the
design patterns.
Expand Down
2 changes: 0 additions & 2 deletions patterns/chain_of_responsibility.rs

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "rust-design-patterns"
version = "0.1.0"
authors = ["Josh Davis <[email protected]>"]
41 changes: 9 additions & 32 deletions patterns/abstract_factory.rs → rust/src/abstract_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
/*
* Core Trait that defines a Phone
*/
trait Phone {
pub trait Phone {
fn call(&self);
}

/*
* Core Trait that defines a Tablet
*/
trait Tablet {
pub trait Tablet {
fn play_games(&self);
}

/*
* Core Trait that defines a Factory
*/
trait Factory<P: Phone, T: Tablet> {
pub trait Factory<P: Phone, T: Tablet> {
fn new_phone(&self) -> P;
fn new_tablet(&self) -> T;
}
Expand All @@ -30,15 +30,15 @@ trait Factory<P: Phone, T: Tablet> {
* Define our Apple products. Normally these structs would contain a lot more
* data.
*/
struct IPhone;
pub struct IPhone;

impl Phone for IPhone {
fn call(&self) {
println!("Look! I'm calling on an IPhone!");
}
}

struct IPad;
pub struct IPad;

impl Tablet for IPad {
fn play_games(&self) {
Expand All @@ -49,7 +49,7 @@ impl Tablet for IPad {
/*
* Create AppleFactory and implement it for our Apple devices
*/
struct AppleFactory;
pub struct AppleFactory;

impl Factory<IPhone, IPad> for AppleFactory {
fn new_phone(&self) -> IPhone {
Expand All @@ -66,15 +66,15 @@ impl Factory<IPhone, IPad> for AppleFactory {
* simplified.
*/

struct Nexus4;
pub struct Nexus4;

impl Phone for Nexus4 {
fn call(&self) {
println!("Look! I'm calling on a Nexus 4!");
}
}

struct Nexus10;
pub struct Nexus10;

impl Tablet for Nexus10 {
fn play_games(&self) {
Expand All @@ -85,7 +85,7 @@ impl Tablet for Nexus10 {
/*
* Create GoogleFactory and implement it for our Google devices
*/
struct GoogleFactory;
pub struct GoogleFactory;

impl Factory<Nexus4, Nexus10> for GoogleFactory {
fn new_phone(&self) -> Nexus4 {
Expand All @@ -96,26 +96,3 @@ impl Factory<Nexus4, Nexus10> for GoogleFactory {
return Nexus10;
}
}


fn main() {
// Create our two different factories
let apple = AppleFactory;
let google = GoogleFactory;

// Both factories use the same interface, so let's just use them

// Test out creating phones
let phone = apple.new_phone();
phone.call();

let phone = google.new_phone();
phone.call();

// Test out creating tablets
let tablet = apple.new_tablet();
tablet.play_games();

let tablet = google.new_tablet();
tablet.play_games();
}
38 changes: 7 additions & 31 deletions patterns/adapter.rs → rust/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/*
* Core Trait that defines a basic Rocket Ship
*/
trait RocketShip {
pub trait RocketShip {
fn turn_on(&self);
fn turn_off(&self);
fn blast_off(&self);
Expand All @@ -16,7 +16,7 @@ trait RocketShip {
/*
* Basic struct for a NASA Ship
*/
struct NASAShip;
pub struct NASAShip;

/*
* Implement RocketShip trait to add functionality to NASAShip
Expand All @@ -43,7 +43,7 @@ impl RocketShip for NASAShip {
* Uh oh, here is our problem. It's the amazingly advanced SpaceX ship that our
* astronaut doesn't know how to pilot.
*/
trait SpaceXShip {
pub trait SpaceXShip {
fn ignition(&self);
fn on(&self);
fn off(&self);
Expand All @@ -54,7 +54,7 @@ trait SpaceXShip {
/*
* Basic struct for a SpaceX Dragon rocket ship
*/
struct SpaceXDragon;
pub struct SpaceXDragon;

/*
* Implement the SpaceX trait to add functionality to the Space X Dragon
Expand Down Expand Up @@ -89,8 +89,8 @@ impl SpaceXShip for SpaceXDragon {
/*
* Adapter to adapt anything that implements SpaceXShip to the RocketShip trait
*/
struct SpaceXAdapter {
ship: SpaceXDragon
pub struct SpaceXAdapter {
pub ship: SpaceXDragon
}

/*
Expand Down Expand Up @@ -118,34 +118,10 @@ impl RocketShip for SpaceXAdapter {
/*
* Basic function to pilot ships that implement the RocketShip trait
*/
fn pilot<S: RocketShip>(ship: &S) {
pub fn pilot<S: RocketShip>(ship: &S) {
ship.turn_on();
ship.blast_off();
ship.fly();
ship.turn_off();
print!("\n");
}

fn main() {
// Create a new NASAShip
let saturn5 = NASAShip;

// Let's fly our NASAShip
println!("Piloting the Saturn 5.");
pilot(&saturn5);

// Create a Dragon
let dragon = SpaceXDragon;

// Uh oh, our pilot function doesn't recognize this ship...
// pilot(&dragon); <-- Gives a compile time error.

// Let's Adapt our SpaceXDragon ship
let dragon_adapter = SpaceXAdapter {
ship: dragon
};

// Now we can pilot the Dragon!
println!("Piloting the Dragon Adapter.");
pilot(&dragon_adapter);
}
Empty file.
88 changes: 88 additions & 0 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
pub mod abstract_factory;
pub mod adapter;
pub mod chain_of_responsibility;
pub mod strategy;

fn start_design_pattern(message: &'static str) {
println!("\n###########################################");
println!("{}", message);
println!("###########################################");
}

fn main() {
use abstract_factory::*;
use adapter::*;
use strategy::*;

println!("Hello, design patterns!");

start_design_pattern("Let's start with the Abstract Factory Pattern :");

// Create our two different factories
let apple = AppleFactory;
let google = GoogleFactory;

// Both factories use the same interface, so let's just use them

// Test out creating phones
let phone = apple.new_phone();
phone.call();

let phone = google.new_phone();
phone.call();

// Test out creating tablets
let tablet = apple.new_tablet();
tablet.play_games();

let tablet = google.new_tablet();
tablet.play_games();

start_design_pattern("Next is a few examples of the Adapater Pattern :");

// Create a new NASAShip
let saturn5 = NASAShip;

// Let's fly our NASAShip
println!("Piloting the Saturn 5.");
pilot(&saturn5);

// Create a Dragon
let dragon = SpaceXDragon;

// Uh oh, our pilot function doesn't recognize this ship...
// pilot(&dragon); <-- Gives a compile time error.

// Let's Adapt our SpaceXDragon ship
let dragon_adapter = SpaceXAdapter {
ship: dragon
};

// Now we can pilot the Dragon!
println!("Piloting the Dragon Adapter.");
pilot(&dragon_adapter);

start_design_pattern("What about some Strategy Pattern :");

// When you start to learn how to ride a bike, it might be dangerous
// to ride a super fast bike with several gears. So let's start
// with a single speed bycicle
let mut my_bycicle = Bycicle::new(Box::new(SingleSpeedShifter::new()));
// [...] You've been riding for a long time now so you feel confident to
// shift gears.
my_bycicle.shift_up();
my_bycicle.shift_down();

// But you can't do that with your current bike...
// So, let's have a brand new road bike shifter!
// But don't go too fast, just get a 3 gears shifter for now
my_bycicle.replace_shifter(Box::new(RoadBikeShifter::new(3)));
// And try to shift up
my_bycicle.shift_up();
my_bycicle.shift_up();
my_bycicle.shift_up(); // Don't bee too greedy, there is only 3 gears on this bike
// Now you can slow down
my_bycicle.shift_down();
my_bycicle.shift_down();
my_bycicle.shift_down(); // Uh oh, you gonna break things down if you go lower than first gear
}
Loading