Skip to content

Instantly share code, notes, and snippets.

@joaofnds
Created August 29, 2018 03:29
Show Gist options
  • Select an option

  • Save joaofnds/63fdd7cf7b72c39372b801b8f664b72f to your computer and use it in GitHub Desktop.

Select an option

Save joaofnds/63fdd7cf7b72c39372b801b8f664b72f to your computer and use it in GitHub Desktop.
// http://www.newthinktank.com/2012/11/visitor-design-pattern-tutorial/
// https://www.youtube.com/watch?v=pL4mOUDi54o
interface Visitor {
visitLiquor(liquorItem: Liquor): number;
visitTobacco(tobaccoItem: Tobacco): number;
visitNecessity(necessityItem: Necessity): number;
}
class TaxVisitor implements Visitor {
visitLiquor(liquorItem: Liquor): number {
const tax = liquorItem.price * 0.18;
return liquorItem.price + tax;
}
visitTobacco(tobaccoItem: Tobacco): number {
const tax = tobaccoItem.price * 0.21;
return tobaccoItem.price + tax;
}
visitNecessity(necessityItem: Necessity): number {
const tax = 0;
return necessityItem.price + tax;
}
}
class TaxHolydayVisitor implements Visitor {
visitLiquor(liquorItem: Liquor): number {
const tax = liquorItem.price * 0.18 * 2;
return liquorItem.price + tax;
}
visitTobacco(tobaccoItem: Tobacco): number {
const tax = tobaccoItem.price * 0.21 * 2;
return tobaccoItem.price + tax;
}
visitNecessity(necessityItem: Necessity): number {
const tax = 0 * 2;
return necessityItem.price + tax;
}
}
interface Visitable {
accept(visitor: Visitor): number;
}
class Liquor implements Visitable {
price: number;
constructor(price: number) {
this.price = price;
}
accept(visitor: Visitor): number {
return visitor.visitLiquor(this);
}
}
class Necessity implements Visitable {
price: number;
constructor(price: number) {
this.price = price;
}
accept(visitor: Visitor): number {
return visitor.visitNecessity(this);
}
}
class Tobacco implements Visitable {
price: number;
constructor(price: number) {
this.price = price;
}
accept(visitor: Visitor): number {
return visitor.visitTobacco(this);
}
}
const taxVisitor = new TaxVisitor();
const taxHolydayVisitor = new TaxHolydayVisitor();
const liquor = new Liquor(10);
const tobacco = new Tobacco(10);
const necessity = new Necessity(10);
console.log("Normal Tax");
console.table({
liquor: liquor.accept(taxVisitor),
tobacco: tobacco.accept(taxVisitor),
necessity: necessity.accept(taxVisitor)
});
/**
* Normal Tax
* ┌───────────┬────────┐
* │ (index) │ Values │
* ├───────────┼────────┤
* │ liquor │ 11.8 │
* │ tobacco │ 12.1 │
* │ necessity │ 10 │
* └───────────┴────────┘
*/
console.log("Holyday Tax");
console.table({
liquor: liquor.accept(taxHolydayVisitor),
tobacco: tobacco.accept(taxHolydayVisitor),
necessity: necessity.accept(taxHolydayVisitor)
});
/**
* Holyday Tax
* ┌───────────┬────────┐
* │ (index) │ Values │
* ├───────────┼────────┤
* │ liquor │ 13.6 │
* │ tobacco │ 14.2 │
* │ necessity │ 10 │
* └───────────┴────────┘
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment