Skip to content

Instantly share code, notes, and snippets.

@dsci
Created July 15, 2019 18:40
Show Gist options
  • Save dsci/73d3d184ad3fe33154b0fe3f1e0cddc9 to your computer and use it in GitHub Desktop.
Save dsci/73d3d184ad3fe33154b0fe3f1e0cddc9 to your computer and use it in GitHub Desktop.
Strategy Pattern - Typescript // Duck Behaviour
import { expect } from 'chai';
import 'mocha';
import {
FlyWithWings,
FlyNoWay,
Quack,
MuteQuack,
Duck,
DuckWithAlternativeConstructor
} from './duck';
describe('Duck Behaviours', () => {
describe('Fly behaviour', () => {
it('should fly', () => {
const duckBehaviour = new FlyWithWings();
expect(duckBehaviour.fly()).to.eq("I can fly");
});
});
describe('Quack behaviour', () => {
it('should quack', () => {
const duckBehaviour = new Quack();
expect(duckBehaviour.quack()).to.eq("Quack");
});
})
describe('No fly behaviour', () => {
it('should not fly', () => {
const duckBehaviour = new FlyNoWay();
expect(duckBehaviour.fly()).to.eq("I can't fly");
});
});
describe('No quack behaviour', () => {
it('should not quack', () => {
const duckBehaviour = new MuteQuack();
expect(duckBehaviour.quack()).to.eq("-silence-");
});
});
});
describe('A duck that is', () => {
const newBornDuck = new Duck();
describe('a newly born duck', ()=> {
it("can't fly", () => {
expect(newBornDuck.performFly()).to.eq("I can't fly");
});
it("can't quack", () => {
expect(newBornDuck.performQuack()).to.eq("-silence-");
})
});
describe('A grownn duck', ()=> {
const grownDuck = new Duck();
before(()=> {
grownDuck.quackBehaviour = new Quack();
grownDuck.flyBehaviour = new FlyWithWings();
});
it("can fly", () => {
expect(grownDuck.performFly()).to.eq("I can fly");
});
it("can quack", () => {
expect(grownDuck.performQuack()).to.eq("Quack");
});
});
describe('A grown duck who got the strategies passed in the constructor', ()=> {
const grownDuck = new Duck(new FlyWithWings(),
new Quack())
it("can fly", () => {
expect(grownDuck.performFly()).to.eq("I can fly");
});
it("can quack", () => {
expect(grownDuck.performQuack()).to.eq("Quack");
})
});
describe('An old duck who got the strategies passed in the constructor', ()=> {
const duckBehaviour = {
quackBehaviour: new Quack()
};
const grownDuck = new DuckWithAlternativeConstructor(duckBehaviour);
it("can't fly", () => {
expect(grownDuck.performFly()).to.eq("I can't fly");
});
it("can quack", () => {
expect(grownDuck.performQuack()).to.eq("Quack");
})
});
});
interface IFlyBehaviour {
fly(): string
}
interface IQuackBehaviour {
quack(): string
}
interface IDuck {
performFly(): string;
performQuack(): string;
}
export class FlyWithWings implements IFlyBehaviour {
public fly(): string {
return 'I can fly';
}
}
export class FlyNoWay implements IFlyBehaviour {
public fly(): string {
return "I can't fly";
}
}
export class Quack implements IQuackBehaviour {
public quack(): string {
return "Quack";
}
}
export class MuteQuack implements IQuackBehaviour {
public quack(): string {
return "-silence-";
}
}
export class Duck implements IDuck{
constructor(private _flyBehaviour: IFlyBehaviour = new FlyNoWay(),
private _quackBehaviour: IQuackBehaviour = new MuteQuack()) {
}
public performFly(): string {
return this._flyBehaviour.fly();
}
public performQuack(): string {
return this._quackBehaviour.quack();
}
public set quackBehaviour(behaviour: IQuackBehaviour) {
this._quackBehaviour = behaviour;
}
public set flyBehaviour(behaviour: IFlyBehaviour) {
this._flyBehaviour = behaviour;
}
}
interface IDuckBehaviour {
quackBehaviour?: IQuackBehaviour
flyBehaviour?: IFlyBehaviour
}
export class DuckWithAlternativeConstructor implements IDuck {
public flyBehaviour: IFlyBehaviour = new FlyNoWay();
public quackBehaviour: IQuackBehaviour = new MuteQuack();
constructor(behaviour?: IDuckBehaviour) {
if (behaviour) Object.assign(this, behaviour);
}
public performFly(): string {
return this.flyBehaviour.fly();
}
public performQuack(): string {
return this.quackBehaviour.quack();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment