Blog#50: Javascript Design Patterns 😊 (Series: Bí kíp Javascript – PHẦN 41)

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo 😊. Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😉. Singleton Pattern | Factory Pattern | Constructor Pattern Topics Singleton Pattern Factory Pattern Factory Pattern vs Constructor Pattern Singleton Pattern (Sử dụng

image.png

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo 😊.
Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😉.

Singleton Pattern | Factory Pattern | Constructor Pattern

Topics

  • Singleton Pattern
  • Factory Pattern
  • Factory Pattern vs Constructor Pattern

Singleton Pattern (Sử dụng Redux hoặc React Context)

  • Singleton Design Patterns để control một instance duy nhất có thể được sử dụng bởi nhiều component.
  • Singleton Pattern có thể được coi là cốt lõi của các thư viện quản lý global state như Redux hay React Context .
  • Là một Pattern nhằm hạn chế một Class chỉ được tạo một instance.
  • Chúng có thể được truy cập trên global và hoạt động như một điểm truy cập duy nhất khi cần truy cập đến các global state.

Ví dụ:

let instance;let globalState ={
  color:""};classStateUtility{constructor(){if(instance){thrownewError("New instance cannot be created!!");}
    instance =this;}getPropertyByName(propertyName){return globalState[propertyName];}setPropertyValue(propertyName, propertyValue){
    globalState[propertyName]= propertyValue;}}let stateUtilityInstance = Object.freeze(newStateUtility());exportdefault stateUtilityInstance;
  • Đảm bảo rằng globalState là private. Bằng cách sử dụng các hàm của StateUtility để truy cập chúng. Bằng cách này, bảo vệ global state không bị thay đổi hoặc truy cập trực tiếp.
  • Cuối cùng, tạo instance của StateUtility như sau: let stateUtilityInstance = Object.freeze(new StateUtility());.
  • Sử dụng Object.freeze để không có class/component/module nào khác có thể sửa đổi tệp stateUtilityInstance.

Factory Pattern (Factory pattern vs Constructors)

  • Một Factory là một Object/Function/Class trong mô hình lập trình hướng function dùng để tạo các đối tượng.
  • Factory Method tạo các đối tượng mới theo một hướng dẫn hoặc điều kiện đã được chỉ định từ trước. Thay vì sử dụng cách thông thường để tạo các đối tượng trong JavaScript là gọi một hàm khởi tạo với toán tử new.
  • Factory design pattern được sử dụng khi có một superclass với nhiều sub-classes và dựa trên input, sẽ trả về một trong các class con tương ứng . Pattern này đảm nhận trách nhiệm khởi tạo một Class thông qua các Factory Method.
  • Factory Methods thường được sử dụng trong các ứng dụng quản lý, maintenance hoặc thao tác với các tập hợp đối tượng khác nhau nhưng đồng thời có nhiều đặc điểm chung (tức là các Function và Properties) .
  • Factory pattern có thể sử dụng constructor hoặc class bên trong. Nhưng Factory pattern được ưu tiên hơn trong trường hợp quá trình tạo đối tượng phụ thuộc vào các yếu tố linh động — chẳng hạn như khi muốn tạo linh động các sub-classes.
  • Factory pattern cung cấp cho một cơ chế tạo đối tượng vừa linh hoạt vừa có thể tái sử dụng.

OK liệt kê một loạt các định nghĩa của Factory pattern chắc ae cũng chuẩn bị tẩu hỏa nhập ma rồi đúng ko.
Vào ví dụ thôi nào:

// creates factory functionfunctionvehicleFactory(manufacturer, plateNO){return{
        manufacturer,
        plateNO,startEngine(){
            console.log("reving engine")},drive(){
            console.log("driving car...")}}}const Vehicle1 =vehicleFactory("Toyota",12345);
console.log(Vehicle1)// prints //{//  manufacturer: 'Toyota',//  plateNO: 12345,//  startEngine: [Function: startEngine],//  drive: [Function: drive]//}const Vehicle2 =vehicleFactory("Ford",13345);
console.log(Vehicle2)// prints // {//  manufacturer: 'Ford',//  plateNO: 13345,//  startEngine: [Function: startEngine],//  drive: [Function: drive]// }
  • Factory pattern tăng khả năng tái sử dụng code bằng cách tái sử dụng các hàm StartEngine, driveVehiclestopEngine.
classCar{constructor(options){this.wheels = options.wheels ||4;this.doors = options.doors ||4;this.color = options.color ||"silver";}}classTruck{constructor(options){this.wheels = options.wheels ||6;this.doors = options.doors ||2;this.color = options.color ||"red";}}classFactory{create=(options, vehicleType)=>{if(!vehicleType){return"unable to make vehicle. Please specify a vehicle type and tryagain!"}let vehicle;if(vehicleType ==="car"){
            vehicle =newCar(options);}elseif(vehicleType ==="truck"){
            vehicle =newTruck(options);} 

  
        vehicle.vehicleType = vehicleType;

        vehicle.startEngine=()=> console.log(`Reving ${vehicleType} engine`);

        vehicle.driveVehicle=()=> console.log(`Driving ${vehicleType}...`);

        vehicle.stopEngine=()=> console.log(`Stop ${vehicleType} engine`);return vehicle;}};const vehicleFactory =newFactory();const car = vehicleFactory.create({
    wheels:4,
    doors:2,
    color:"black",},"car");

console.log(car)
console.log(car.startEngine())
console.log(car.driveVehicle())// prints://Car {//  wheels: 4,//  doors: 4,//  color: 'silver',//  vehicleType: 'car',//  startEngine: [Function],//  driveVehicle: [Function],//  stopEngine: [Function]//}// Reving car engine// Driving car...const truck = vehicleFactory.create({
    wheels:4,
 doors:2,
 color:"yellow",},"truck")

console.log(truck)
console.log(truck.startEngine())
console.log(truck.stopEngine())// prints//Truck {//  wheels: 4,//  doors: 2,//  color: 'yellow',//  vehicleType: 'truck',//  startEngine: [Function],//  driveVehicle: [Function],//  stopEngine: [Function]//}// Reving truck engine// Stop truck engine
  • Bằng cách sử dụng Factory pattern, code của chúng ta cũng có thể dễ dàng maintenance, vì vậy nếu sau này dự án có mở rộng và các nhà máy bắt đầu sản xuất các loại phương tiện mới, có thể dễ dàng implement để xử lý vấn đề này như bên dưới:
classCar{constructor(options){this.wheels = options.wheels ||4;this.doors = options.doors ||4;this.color = options.color ||"silver";}}classTruck{constructor(options){this.wheels = options.wheels ||6;this.doors = options.doors ||2;this.color = options.color ||"red";}}classFactory{create=(options, vehicleType)=>{if(!vehicleType){return"unable to make vehicle. Please specify a vehicle type and tryagain!"}let vehicle;if(vehicleType ==="car"){
            vehicle =newCar(options);}elseif(vehicleType ==="truck"){
            vehicle =newTruck(options);} 

  
        vehicle.vehicleType = vehicleType;

        vehicle.startEngine=()=> console.log(`Reving ${vehicleType} engine`);

        vehicle.driveVehicle=()=> console.log(`Driving ${vehicleType}...`);

        vehicle.stopEngine=()=> console.log(`Stop ${vehicleType} engine`);return vehicle;}};const vehicleFactory =newFactory();const car = vehicleFactory.create({
    wheels:4,
    doors:2,
    color:"black",},"car");

console.log(car)
console.log(car.startEngine())
console.log(car.driveVehicle())// prints://Car {//  wheels: 4,//  doors: 4,//  color: 'silver',//  vehicleType: 'car',//  startEngine: [Function],//  driveVehicle: [Function],//  stopEngine: [Function]//}// Reving car engine// Driving car...const truck = vehicleFactory.create({
    wheels:4,
 doors:2,
 color:"yellow",},"truck")

console.log(truck)
console.log(truck.startEngine())
console.log(truck.stopEngine())// prints//Truck {//  wheels: 4,//  doors: 2,//  color: 'yellow',//  vehicleType: 'truck',//  startEngine: [Function],//  driveVehicle: [Function],//  stopEngine: [Function]//}// Reving truck engine// Stop truck engine
  • Tất nhiên Factory pattern vì nó là một Design Pattern chuẩn HÀNG AUTH => Các bạn hoàn toàn có thể apply nó bằng cách dùng Function thay vì dùng Class. Tùy thuộc vào ngôn ngữ lập trình thì cách apply nó sẽ khác nhau nhưng về tư tưởng thì Factory pattern sẽ gần như là giống nhau.
varFactory=function(){this.createEmployee=function(type){var employee;if(type ==="fulltime"){
            employee =newFullTime();}elseif(type ==="parttime"){
            employee =newPartTime();}elseif(type ==="temporary"){
            employee =newTemporary();}elseif(type ==="contractor"){
            employee =newContractor();}

        employee.type = type;

        employee.say=function(){
            console.log(this.type +": rate "+this.hourly +"/hour");}return employee;}}varFullTime=function(){this.hourly ="$12";};varPartTime=function(){this.hourly ="$11";};varTemporary=function(){this.hourly ="$10";};varContractor=function(){this.hourly ="$15";};functionrun(){var employees =[];var factory =newFactory();

    employees.push(factory.createEmployee("fulltime"));
    employees.push(factory.createEmployee("parttime"));
    employees.push(factory.createEmployee("temporary"));
    employees.push(factory.createEmployee("contractor"));for(var i =0, len = employees.length; i < len; i++){
        employees[i].say();}}

Factory pattern vs Constructors

  • Constructor patternFactory pattern tương tự nhau vì chúng là các Pattern dùng để tạo đối tượng trả về một đối tượng mới
  • Factory method có thể trả về một đối tượng đã được tạo, không giống như constructor luôn tạo một instance mới.
  • Các Factory method có ý tưởng lập trình bằng cách sử dụng Interface, sau đó implement, điều này dẫn đến code linh hoạt hơn, trong khi đó constructor pattern liên kết code với một implement cụ thể.
  • Lý do sử dụng constructor: sử dụng constructor để khởi tạo đối tượng với state mặc định hoặc initial state. Các value mặc định của các thuộc tính primitives (number, string, bollean…) có thể không phải là những gì bạn đang tìm kiếm. Một lý do khác để sử dụng constructor là nó sẽ show cho chúng ta về các phụ thuộc (dependencies) của nó.
  • Lý do sử dụng Factory: Factory Method Pattern cho phép các sub-classes chọn loại đối tượng để tạo. Nó có liên kết lỏng lẻo bằng cách loại bỏ nhu cầu liên kết các lớp dành riêng cho từng feature.

Lại tiếp tục xem ví dụ để hiểu rõ hơn phần giải thích ở trên:

const vehicleOptions ={type:"cars", color:"white", doors:4, wheels:4}// factory patternfunctionFactory(options){let factory ={};
  factory.type = options.type;
  factory.color = options.color;
  factory.wheels = options.wheels;
  factory.doors = options.doors;return factory;}const vehicle =Factory(vehicleOptions);// constructor patternfunctionConstructorPattern(options){this.type = options.type;this.color = options.color
  this.doors = options.doors;this.wheels = options.wheels;}const vehicle2 =newConstructorPattern(vehicleOptions);

console.log("factory car", vehicle)// prints { type: 'cars', color: 'white', wheels: 4, doors: 4 }

console.log("constructor car", vehicle2)// prints { type: 'cars', color: 'white', wheels: 4, doors: 4 }

Khi nào nên sử dụng Factory Pattern

Factory Pattern có thể đặc biệt hữu ích khi áp dụng cho các tình huống sau:

  • Khi thiết lập đối tượng hoặc component của liên quan đến mức độ phức tạp cao.
  • Khi cần dễ dàng tạo các instance khác nhau của các đối tượng tùy thuộc vào môi trường hiện tại hoặc một điều kiện nào đó.
  • Khi đang làm việc với nhiều đối tượng hoặc component nhỏ có chung Properties.
  • Khi kết hợp các đối tượng với các instance của các đối tượng khác chỉ cần đáp ứng API contract (a.k.a., duck typing) để hoạt động. Điều này rất hữu ích cho việc tách rời mọi thứ và giảm sự phụ thuộc.

Phần giải thích ở trên có thể khá khô khan các bạn cố gắng xem kỹ ví dụ sẽ giễ dàng hiểu chúng hơn.
Trong dự án hiện tại của mình thì sử dụng rất nhiều Factory Design Pattern này. Một khi các bạn nắm được nó sẽ thấy nó thật là đơn giản nhưng ko kém phần mạnh mẽ.

Roundup

Như mọi khi, mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.

Cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo! 😍

Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé. Thank you.😉

Ref

Nguồn: viblo.asia

Bài viết liên quan

Sự Khác Nhau Giữa Domain và Hosting Là Gì?

Sự khác nhau giữa domain và hosting là gì? Bài này giải thích ngắn và dễ hiểu nh

Shared Hosting hay VPS Hosting: Lựa chọn nào dành cho bạn?

Bài viết giải thích rõ shared hosting và vps hosting là gì và hướng dẫn chọn lựa

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=