Design Patterns in JavaScript Constructor, Factory, & Abstract Factory Creational Patterns
<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>