Skip to content
BBaskaran

Factory Method

Define an interface for creating an object, but let subclasses decide which class to instantiate.

Use it when

A class can't anticipate the exact type of objects it must create.

// Factory Method
interface CreditCard {
	getCardType(): string;
	getCreditLimit(): number;
	getAnnualCharges(): number;
}

class VisaCard implements CreditCard {
	public getCardType(): string {
		return ("Visa Card");
	}
	public getCreditLimit(): number {
		return 20000;
	}
	public getAnnualCharges(): number {
		return 500;
	}
}

class PlatinumCard implements CreditCard {
	public getCardType(): string {
		return ("Platinum Card");
	}
	public getCreditLimit(): number {
		return 25000;
	}
	public getAnnualCharges(): number {
		return 600;
	}
}

abstract class CardCreator {
	public abstract cardFactory(): CreditCard;

	public doOperation(): string {
		const product = this.cardFactory();

		const res = {
			"Abstract Card Creator": {
				CardType: product.getCardType(),
				CreditLimit: product.getCreditLimit(),
				AnnualCharges: product.getAnnualCharges()
			}
		};

		return JSON.stringify(res, null, 2);
					 
	}
}

class ConcreteCreator extends CardCreator {
	private key: string = "VISACARD";

	constructor(str: string) {
		super();
		this.key = str;
	}

	public cardFactory(): CreditCard {
		if (this.key === "VISACARD") {
			return new VisaCard();
		} else if (this.key === "PLATINUM") {
			return new PlatinumCard();
		}
		return new VisaCard();
	}
}

const clientCode = (creator: CardCreator) => {
	console.log("Client: I'm not aware of creator's class");
	console.log(creator.doOperation());
}

clientCode(new ConcreteCreator("VISACARD"));
clientCode(new ConcreteCreator("PLATINUM"));