Strategy Example (Typescript)

In this example below you will see how to do a Strategy Example (Typescript) with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by Frontender, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright Frontender ©
  • HTML
  • CSS
  • JavaScript
    <h1>Strategy Example (Typescript)</h1>
<p>Certain algorithms (how to calculate salary here) can be separated from the main Component (Worker in this case) and put aside as a hierarchy of classes. Then, upon instantiation of the Component chosen algorithm can be placed into new instance of our Component and used further to fulfil its task.</p>
<button id="sender1">Waiter salary</button>
<button id="sender2">Accountant salary</button>
<button id="reset">Reset</button>
<br>
<div class="items" id="salaries">
  <header>Salaries:</header>
</div>
<br>

/*Downloaded from https://www.codeseek.co/curveball/strategy-example-typescript-bgjWRV */
    body {padding:10px;}
#receiver {
  border:1px solid gray;
  width:25%;
  margin-top:1em;
  padding: 5px;
}
div.items {
  overflow:auto; 
  padding:10px; 
  border:1px solid #222; 
  margin-top:10px; 
  display:inline-block;
}
div.items div, div.items header {
  border-bottom:1px solid #000;
  margin-bottom:10px;
}


/*Downloaded from https://www.codeseek.co/curveball/strategy-example-typescript-bgjWRV */
    namespace StrategyArea {
  // Component
  abstract class Worker {
    protected unit: string;
    protected name: string;
    protected duration: number;
    constructor(protected salaryStrategy: salaryStrategy) { }
    public salary(): string {
      return this.salaryStrategy.salary(this);
    }
    public getName(): string {
      return this.name;
    }
    public getUnit(): string {
      return this.unit;
    }
    public getDuration(): number {
      return this.duration;
    }
  }
  // Accountants are paid per hour
  class Accountant extends Worker {
    constructor(protected salaryStrategy: salaryStrategy) {
      super(salaryStrategy);
      this.unit = 'hours';
      this.name = 'Accountant';
      this.duration = +prompt(`Insert number of ${this.unit}`, '0');

    }
  }
  // Waiter are paid per shift
  class Waiter extends Worker {
    constructor(protected salaryStrategy: salaryStrategy) {
      super(salaryStrategy);
      this.unit = 'shifts';
      this.name = 'Waiter';
      this.duration = +prompt(`Insert number of ${this.unit}`, '0');

    }
  }
  // Salary strategies
  abstract class salaryStrategy {
    constructor(protected ratePerUnit: number) {}
    public abstract salary(worker: Worker): string;
  }
  class hourSalaryStrategy extends salaryStrategy {
    public salary(worker: Worker): string {
      return worker.getName() + ': ' + (this.ratePerUnit * worker.getDuration()) + '$ for ' + worker.getDuration() + ' ' + worker.getUnit();
    }
  }
  class shiftSalaryStrategy extends salaryStrategy {
    public salary(worker: Worker): string {
      return worker.getName() + ': ' + (this.ratePerUnit * worker.getDuration()) + '$ for ' + worker.getDuration() + ' ' + worker.getUnit();
    }
  }
  // Run it all
  class Setup {
    private elem: HTMLElement = document.getElementById('salaries');

    private removeMsg(elem: HTMLElement): void {
      let msgs: HTMLElement[] = Array.prototype.slice.call(elem.children);
      msgs.forEach((element: HTMLElement) => {
       if(element.tagName != 'header'.toUpperCase()) element.remove()
      });
    }
    private addRecord(salary: string): void {
      let record: HTMLElement = document.createElement('div');
      record.textContent = salary;
      this.elem.appendChild(record);
    }
    public run():void {
      // display Waiter's salary
      let btn1: HTMLElement = document.getElementById("sender1");
      btn1.addEventListener("click", () => {
      let waiter: Worker = new Waiter( new shiftSalaryStrategy(85) );
      let salary: string = waiter.salary();
      this.addRecord(salary);
      });
      // display Accountant's salary
      let btn2: HTMLElement = document.getElementById("sender2");
      btn2.addEventListener("click", () => {
      let accountant: Worker = new Accountant( new hourSalaryStrategy(15) );
      let salary: string = accountant.salary();
      this.addRecord(salary);
      });
      let reset: HTMLElement = document.getElementById("reset"); // clean table
      reset.addEventListener("click", () => this.removeMsg(this.elem) );
    }
  }
  let setup = new Setup();
  setup.run();
}

Comments