+5

[Javascript] Factory Design Pattern

Trước khi vào bài, mình xin chúc toàn thể anh em trong cộng đồng có một năm mới thật bình an, sức khỏe thật dồi dào và gặt hái được thật nhiều may mắn, thành công trong sự nghiệp và cuộc sống nhé ❤️

Ok anh em mình cùng bắt đầu nào.

Lý thuyết

Factory Design Pattern là một Creational Design Pattern, cung cấp 1 giao diện chung (ở đây có thể là Class, Hàm) giúp việc tạo đối tượng linh hoạt hơn.


Ví dụ minh họa

Dưới đây là ví dụ một họa để anh em mình nắm rõ hơn về Factory Design Pattern nhé.

  1. Tạo 2 class Cat và Dog.
  2. Tạo một Factory class AnimalFactory với hàm create để tạo đối tượng theo tham số type truyền vào.
class Cat { 
    constructor(options) {
        this.name = options.name;
    }
}
class Dog { 
    constructor(options) {
        this.name = options.name;
    }
}
class AnimalFactory {
    create(type, options) {
        if(type == 'cat') return new Cat(options);
        else if(type == 'dog') return new Dog(options);
    }
}
var animalFactory = new AnimalFactory();
var dog = animalFactory.create("dog", {name: "Pi"});
console.log(dog); // {name: 'Pi'}

Việc tạo đối tượng giờ đây chỉ cần thông qua một giao diện chung, ở đây chính là hàm create trong class AnimalFactory. Đây cũng chính là tư tưởng cơ bản của Factory Design Pattern.

Tuy nhiên, anh em mình có thể thấy vấn đề bắt đầu phát sinh khi cần bổ sung thêm đối tượng mới. Khi đó, ta cần phải bổ sung điều kiện tạo mới đối tượng trong hàm create.

Ví dụ ta cần thêm đối tượng Bird. Ta tạo mới class Bird và phải sửa lại hàm create trong AnimalFactory.

class Bird { 
    constructor(options) {
        this.age = options.age;
    }
}
class AnimalFactory {
    create(type, options) {
        if(type == 'cat') return new Cat(options);
        else if(type == 'dog') return new Dog(options);
        else if(type == 'bird') return new Bird(options); // bổ sung điều kiện tạo đối tượng Bird
    }
}
var animalFactory = new AnimalFactory();
var bird = animalFactory.create("bird", {name: "Birddd"});

Đấy là còn chưa kể nếu cần bổ xung nhiều đối tượng khác, hàm create sẽ phình to hơn. Điều này vi phạm nguyên tắc Open/closed principle trong SOLID (anh em có thể tự google để tìm hiểu thêm về SOLID nhé).

Để giải quyết việc sửa đổi hàm, ta tạo 1 object giúp xử lý mapping các đối tượng.

var objectMapping = {
    cat: Cat,
    dog: Dog,
    bird: Bird
}
class AnimalFactory {
    create(type, options) {
        let animal = objectMapping[type];
        return new animal(options);
    }
}
var animalFactory = new AnimalFactory();
var dog = animalFactory.create("dog", {name: "Pi"});

Nếu cần bổ sung thêm đối tượng, ta chỉ việc thêm đối tượng đó vào biến objectMapping. Qua đó, giúp hạn chế được việc sửa đổi hàm create trong class AnimalFactory.

Đó, anh em có thể thấy cách triển khai Factory Design Pattern không hề khó đúng không.


Bonus

Tiện bài mình cũng muốn chia sẻ thêm với anh em, chúng ta có thể ứng dụng cách viết mapping đối tượng phía trên vào việc viết hàm xử lý nhiều điều kiện.

Ví dụ, anh em cần viết 1 hàm để xử lý mapping trường như sau:

function handleMapping(o) {
    if(o.displayField == "OrgID") {
        o.Caption == "Cơ cấu tổ chức";
        o.ShortName == "CCTC";
        o.DataType == 1;
    } else if(e.displayField == "JobID") {
        o.Caption == "Vị trí công việc";
        o.DataType == 2;
    }
}

Để code trở nên linh hoạt, ngắn gọn, dễ quản lý hơn. Áp dụng phương pháp bên trên, anh em tạo 1 objMapping để xử lý việc mapping trường.

let objMapping = {
    OrgID: {
        Caption: "Cơ cấu tổ chức",
        ShortName: "CCTC",
        dataType: 1
    },
    JobID: {
        Caption: "Vị trí công việc",
        dataType: 2
    }
}
function handleMapping(o) {
    if(objMapping[o.displayField]) {
        o = {
            ...o,
            ...objMapping[o.displayField]
        }
    }
}

Với cách áp dụng trên, anh em sẽ không phải sửa đổi hàm handleMapping khi cần bổ sung thêm điều kiện mapping trường mới => không vi phạm nguyên tắc Open/closed principle trong SOLID.


Kết

Với việc áp dụng Factory Design Pattern, anh em có thể thấy việc tạo đối tượng đã trở nên dễ dàng, dễ quản lý hơn nhiều đúng không 😃

Hi vọng bài viết sẽ giúp ích cho anh em. Cảm ơn anh em nhiều !!!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.