Skip to content

Instantly share code, notes, and snippets.

@juan-m-medina
Created February 17, 2016 16:21
Show Gist options
  • Save juan-m-medina/7803acdf73c0031e2f69 to your computer and use it in GitHub Desktop.
Save juan-m-medina/7803acdf73c0031e2f69 to your computer and use it in GitHub Desktop.
LunchNLearn - Mixins
// General library function to apply mixins to classes
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
})
});
}
// An Enum to classify items for pricing
enum Fruits {
Apple,
Pear,
Grape,
Orange
}
// Item Definition
class Item {
constructor(options? : { type: Fruits, description : string}) {
this.type = options.type;
this.description = options.description;
}
type : Fruits;
description : string;
}
// Item + Quantity
class LineItem extends Item {
quantity : number;
constructor(options? : { type: Fruits, description : string, quantity : number}) {
super( { type: options.type, description : options.description});
this.quantity = options.quantity;
}
}
// Address + static methods
class Address {
number : number;
street : string;
suffix : string;
city : string;
state : string;
zip : number;
zip4 : number
}
// Item Pricer
class ItemPricer {
getPrice(item : Item) : number {
if (item.type == Fruits.Apple) return 10;
if (item.type == Fruits.Pear) return 20;
if (item.type == Fruits.Grape) return 30;
if (item.type == Fruits.Orange) return 40;
}
}
// Line Item Pricer (Item Pricer * quantity)
class LineItemPricer implements ItemPricer {
getPrice : (item : Item) => number;
priceLineItem(item : LineItem) {
return this.getPrice(item) * item.quantity;
}
}
// Setup the Pricer mixin
applyMixins(LineItemPricer, [ItemPricer]);
// Class to determine whether to insure the invoce
class Insurable {
lowLimit : number = 10;
requiresInsurance(price : number) : Boolean {
if (price > this.lowLimit) {
return true;
}
return false;
}
}
// Invoice Builder combining all the other stuff
class InvoiceBuilder implements LineItemPricer, Insurable {
lineItems : LineItem[];
lowLimit : number;
getPrice : (item : Item) => number;
priceLineItem : (item : LineItem) => number;
requiresInsurance : (price : number) => boolean;
constructor(lowLimit : number = 150, lineItems : LineItem[]) {
this.lowLimit = lowLimit;
this.lineItems = lineItems;
}
build() {
let lineItemNumber = 1;
let totalInvoicePrice = 0;
// Table creation
let table = document.createElement('table');
let tableHeader = <HTMLTableElement> table.createTHead();
let headerRow = <HTMLTableRowElement> tableHeader.insertRow(0);
let tableBody = <HTMLTableElement> table.createTBody();
// Header creation
let lineItemNumberHeaderCell = headerRow.insertCell();
lineItemNumberHeaderCell.innerText = "Item Number";
let descriptionHeaderCell = headerRow.insertCell();
descriptionHeaderCell.innerText = "Description";
let unitPriceHeaderCell = headerRow.insertCell();
unitPriceHeaderCell.innerText = "Unit Price";
let quantityHeaderCell = headerRow.insertCell();
quantityHeaderCell.innerText = "Quantity";
let lineItemPriceHeaderCell = headerRow.insertCell();
lineItemPriceHeaderCell.innerText = "Total Price";
// Table content creation
for(let lineItem of this.lineItems) {
let row = <HTMLTableRowElement> tableBody.insertRow();
let lineItemNumberCell = row.insertCell();
lineItemNumberCell.innerText = lineItemNumber.toString();
let descriptionCell = row.insertCell();
descriptionCell.innerText = lineItem.description;
let unitPriceCell = row.insertCell();
unitPriceCell.innerText = this.getPrice(lineItem).toString();
let quantityCell = row.insertCell();
quantityCell.innerText = lineItem.quantity.toString();
let lineItemPriceCell = row.insertCell();
let lineItemPrice = this.priceLineItem(lineItem);
lineItemPriceCell.innerText = lineItemPrice.toString();
totalInvoicePrice += lineItemPrice;
lineItemNumber++;
}
let footerText = document.createElement('div');
footerText.innerText = `The total price for the invoice is ${totalInvoicePrice.toString()}, and it ${this.requiresInsurance(totalInvoicePrice) === true ? "requires insurance" : "does not require insurance"}`;
document.body.appendChild(footerText);
document.body.appendChild(table);
}
}
applyMixins(InvoiceBuilder, [LineItemPricer, Insurable]);
var sampleLineItems = [
new LineItem ({ type: Fruits.Apple, description : "Best Apples Ever", quantity : 10 }),
new LineItem ({ type: Fruits.Pear, description: "Best Pears Ever", quantity : 3 }),
new LineItem ({ type: Fruits.Grape, description: "Best Grapes Ever", quantity : 5 }),
new LineItem ({ type: Fruits.Orange, description : "Best Oranges Ever", quantity : 7 })
];
var sampleInvoice = new InvoiceBuilder(5000, sampleLineItems).build();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment