<html>
<body>
<h1>Design Patterns in JavaScript Constructor, Factory, & Abstract Factory Creational Patterns</h1>
<script type="text/javascript">
"use strick";
var student={};
console.log("empty student object:",student);
student.name="Alice";
student["university"]="Amazing University";
student.gpa=3.8;
console.log("empty student object with properties:",student);
student.printDetails=function(){
console.log("******* printDetails");
console.log("Name:",this.name,
"University:",this.university,
"GPA",this["gpa"]);
console.log("******* END");
}
console.log("empty student object with function perperties:",student);
student.printDetails();
var another_student=Object.create(Object.prototype);
another_student.name="James";
another_student.university="Intelligent University";
another_student["gpa"]=3.4;
another_student.printDetails=function(){
console.log("******* printDetails");
console.log("Name:",this.name,
"University:",this["university"],
"GPA",this.gpa);
console.log("******* END");
}
console.log("another_student object with perperties:",another_student);
another_student.printDetails();
var yet_another_student=new Object();
yet_another_student.name="Nancy";
yet_another_student.university="Pinnacle University";
yet_another_student["gpa"]=3.3;
yet_another_student.printDetails=function(){
console.log("******* printDetails");
console.log("Name:",this.name,
"University:",this["university"],
"GPA",this.gpa);
console.log("******* END");
}
console.log("yet_another_student object with perperties:",yet_another_student);
yet_another_student.printDetails();
function Student(name,university){
this.name=name;
this.university=university;
this.printDetails=function(){
console.log("******* printDetails");
console.log("Name:",this.name,
"University:",this["university"],
"GPA",this.gpa);
console.log("******* END");
}
}
var student_1=new Student("Nora","Pinnacle University");
console.log("student_1:",student_1);
student_1.printDetails();
student_1.gpa=3.7;
console.log("student_1 gpa:",student_1);
student_1.printDetails();
//All Student object should share the same function object
//Define functions on Student.prototype
//"this" within showDetails()
//Refers to the current instance of the object
Student.prototype.showDetails=function(){
console.log("******* showDetails");
console.log("Name:",this.name,
"University:",this["university"],
"GPA",this.gpa);
console.log("******* END");
}
student_1.showDetails();
var student_2=new Student("Damien","Science University");
student_2.gpa=3.2;
console.log("student_2 gpa:",student_2);
student_2.printDetails();
student_2.showDetails();
//ES6 classes are syntactic sugar over objects created using special function constructors
class StudentClass{
constructor(name,university,gpa){
this.name=name;
this.university=university;
this.gpa=gpa;
this.printDetails=function(){
console.log("******* printDetails");
console.log("Name:",this.name,
"University:",this["university"],
"GPA",this.gpa);
console.log("******* END");
}
}
showDetails=function(){
console.log("******* showDetails");
console.log("Name:",this.name,
"University:",this["university"],
"GPA",this.gpa);
console.log("******* END");
}
}
var student_10=new StudentClass("Robert","Professional University",3.9);
console.log("student_10:",student_10);
student_10.printDetails();
student_10.showDetails();
//Factory Method,Factory Pattern
//Abstracts away object creation details using an interface which can be used to create different objects
class Vehicle{
constructor(vehicleType,make,model){
this.vehicleType=vehicleType;
this.make=make;
this.model=model;
}
printDetails(){
console.log("Vehicle Type:",this.vehicleType,
"Make:",this.make,
"Model",this.model);
}
//for abstract factory
drive(){
console("Drive:",this.vehicleType,this.make,this.model);
}
fillFue(){
console("Fill fuel:",his.vehicleType,this.make,this.model);
}
};
class Car extends Vehicle{
constructor(details){
super("car",details.make,details.model);
this.carType=details.carType;
}
printDetails(){
console.log("*********printDetails");
super.printDetails();
console.log("Car Type:",this.carType);
console.log("*********end");
}
};
class Truck extends Vehicle{
constructor(details){
super("truck",details.make,details.model);
this.truckType=details.truckType;
}
printDetails(){
console.log("*********printDetails");
super.printDetails();
console.log("Truck Type:",this.truckType);
console.log("*********end");
}
};
//abstract factory
class TwoWheeler extends Vehicle{
constructor(details){
super("twoWheeler",details.make,details.model);
this.twoWheelerType=details.twoWheelerType;
}
printDetails(){
console.log("*********printDetails");
super.printDetails();
console.log("Two-Wheeler Type:",this.twoWheelerType);
console.log("*********end");
}
}
//end
class VehicleFactory{
createVehicle(vehicleType,details){
var vehicleCtor=Car;
if(vehicleType=="car"){
vehicleCtor=Car;
}else if(vehicleType=="truck"){
vehicleCtor=Truck;
}
return new vehicleCtor(details);
}
};
var vehicleFactory=new VehicleFactory();
console.log("Vehicle Factory",vehicleFactory);
var carDetails={
"make":"Honda",
"model":"Civic",
"carType":"sedan"
}
var car=vehicleFactory.createVehicle("car",carDetails);
console.log("Created car: ",car);
console.log("Is instance of Car?",(car instanceof Car));
car.printDetails();
var truckDetails={
"make":"Ashok LeyLand",
"model":"D20B",
"truckType":"flatbed"
}
var truck=vehicleFactory.createVehicle("truck",truckDetails);
console.log("Created Truck: ",truck);
console.log("Is instance of Truck?",(truck instanceof Truck));
truck.printDetails();
//implements factory pattern
class CustomVehicleFactory{
constructor(verhicleType){
if(verhicleType=="car"){
this.vehicleCtor=Car;
}else if(verhicleType=="truck"){
this.vehicleCtor=Truck;
}
}
createVehicle(details){
return new this.vehicleCtor(details);
}
}
var carFactory=new CustomVehicleFactory("car");
console.log("Car factory:",carFactory);
var truckFactory=new CustomVehicleFactory("truck");
console.log("Truck factory:",truckFactory);
var carDetails={
"make":"BMW",
"model":"S series",
"carType":"convertible"
}
console.log("Created car: ",car);
console.log("Is instance of Car?",(car instanceof Car));
car.printDetails();
var truckDetails={
"make":"Western Start",
"model":"A1",
"truckType":"Lowboy trailer"
}
var truck=vehicleFactory.createVehicle("truck",truckDetails);
console.log("Created Truck: ",truck);
console.log("Is instance of Truck?",(truck instanceof Truck));
truck.printDetails();
//Abstract Factory pattern
//Used to create families of related objects i.e.objects that have similar characteristics
class VehicleFactory2{
constructor(vehicleType){
this.vehicleCtor=Car;
switch(vehicleType){
case "car":
this.vehicleCtor=Car;
break;
case "truck":
this.vehicleCtor=Truck;
break;
case "twowheeler":
this.vehicleCtor=TwoWheeler;
break;
}
}
create(details){
return new this.vehicleCtor(details);
}
};
class CarFactory extends VehicleFactory2{
constructor(){
super("car");
}
}
class TruckFactory extends VehicleFactory2{
constructor(){
super("truck");
}
}
class TwoWheelerFactory extends VehicleFactory2{
constructor(){
super("twowheeler");
}
}
//implements
var abstractVehicleFactory=(function(){
var factoryTypes={};
return {
getVehicle:function(vehicleType,details){
var vehicleFactory=factoryTypes[vehicleType];
if(vehicleFactory){
return vehicleFactory.create(details);
}
return null;
},
registerVehicleFactory:function(vehicleType,vehicleFactory){
if(!vehicleFactory.__proto__.create){
throw Error("create() method execpted on the factory");
}
if(!vehicleFactory.vehicleCtor){
throw Erro("vehicleCtor expected on the factory");
}
if(!vehicleFactory.vehicleCtor.prototype.drive||vehicleFactory.vehicleCtor.prototype.fillFuel){
throw Erro("Vehicles constructed should have drive() and fillFuel() method");
}
factoryTypes[vehicleType]=vehicleFactory;
}
};
})(); //Immediately Invoked function a function that is invoked(i.e.executed) as soon as it is defined.
abstractVehicleFactory.registerVehicleFactory("car",new CarFactory());
abstractVehicleFactory.registerVehicleFactory("truck",new TruckFactory());
console.log("abstractVehicleFactory:",abstractVehicleFactory);
//implements
var car2=abstractVehicleFactory.getVehicle("car",carDetails);
console.log("Created car:",car2);
console.log("Is instance of Car?",(car2 instanceof Car));
car2.printDetails();
var truck2=abstractVehicleFactory.getVehicle("truck",truckDetails);
console.log("Created truck:",truck2);
console.log("Is instance of Truck?",(truck2 instanceof Truck));
truck2.printDetails();
var twoWheelerDetails={
"make":"Hero",
"model":"Z23",
"twoWheelerType":"motorbike"
}
var twoWheeler=abstractVehicleFactory.getVehicle("twowheeler",twoWheelerDetails);
console.log("Created twoWheeler:",twoWheeler);
console.log("Is instance of TwoWheeler?",(twoWheeler instanceof TwoWheeler));
console.log("------------Register twoWheelerfactroy--------------");
abstractVehicleFactory.registerVehicleFactory("twowheeler",new TwoWheelerFactory());
twoWheeler=abstractVehicleFactory.getVehicle("twowheeler",twoWheelerDetails);
console.log("Created twoWheeler:",twoWheeler);
console.log("Is instance of TwoWheeler?",(twoWheeler instanceof TwoWheeler));
twoWheeler.printDetails();
</script>
</body>
</html>