Design Pattern - Factory pattern


Factory Pattern là gì?

Factory design pattern là 1 mẫu trong nhóm khởi tạo đối tượng. Trong Factory pattern, người dùng tạo 1 đối tượng mà ko cần biết nó đến từ đâu(class nào được sử dụng để tạo ra đối tượng). Ý tưởng đằng sau factory là đơn giản việc tạo đối tương. Nó đơn giản hơn cho việc theo dỏi đối tượng nào được tạo mà được tạo thông qua một function trung tâm, trái ngược lại với cho phép người dùng tạo đối tượng trực tiếp. Một Factory giúp đơn giản việc tạo đối tượng và sử dụng nó.

Factories có 2 dạng: Factory method, là phương thức trả về các đối tượng khác nhau tùy vào giá trị input; Abstract Factory là nhóm các class được factory method sử dụng để tạo đối tượng.

Cài đặt Factory Pattern như thế nào?

Một Factory Pattern bao gồm các thành phần cơ bản sau:

  • Super Class: môt supper class trong Factory Pattern có thể là một interfaceabstract class hay một class thông thường.
  • Sub Classes: các sub class sẽ implement các phương thức của supper class theo nghiệp vụ riêng của nó.
  • Factory Class: một class chịu tránh nhiệm khởi tạo các đối tượng sub class dựa theo tham số đầu vào. Lưu ý: lớp này là Singleton hoặc cung cấp một public static method cho việc truy xuất và khởi tạo đối tượng. Factory class sử dụng if-else hoặc switch-case để xác định class con đầu ra.

 

Ưu điểm và nhược điểm của Factory Method Pattern

Ưu điểm:

  • Factory Pattern giúp giảm sự phụ thuộc giữa các module (loose coupling): cung cấp 1 hướng tiếp cận với Interface thay thì các implement. Giúp chuơng trình độc lập với những lớp cụ thể mà chúng ta cần tạo 1 đối tượng, code ở phía client không bị ảnh hưởng khi thay đổi logic ở factory hay sub class.
  • Với Pattern này, chúng ta có thể dễ dàng mở rộng, thêm những đoạn code mới vào chương trình mà không cần phá vỡ các đối tượng ban đầu .
  • Factory Method Pattern giúp gom các đoạn code tạo ra product vào một nơi trong chương trình, nhờ đó giúp dễ theo dõi và thao tác.

Nhược điểm:

  • Mã code có thể trở nên phức tạp hơn mức bình thường do đòi hỏi phải sử dụng nhiều class mới có thể cài đặt được pattern này.

Ví dụ mẫu thiết kế Factory Method

class Frog:
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return self.name
    def interact_with(self, obstacle):
        print('{} the Frog encounters {} and {}!'.format(self,obstacle, obstacle.action()))

class Bug:
    def __str__(self):
        return 'a bug'
    def action(self):
        return 'eats it'

class FrogWorld:
    def __init__(self, name):
        print(self)
        self.player_name = name
    def __str__(self):
        return '\n\n\t------ Frog World -------'

    def make_character(self):
        return Frog(self.player_name)
    def make_obstacle(self):
        return Bug()
    
class Wizard:
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return self.name
    def interact_with(self, obstacle):
        print('{} the Wizard battles against {} and {}!'.format(self, obstacle, obstacle.action()))
class Ork:
    def __str__(self):
        return 'an evil ork'
    def action(self):
        return 'kills it'
class WizardWorld:
    def __init__(self, name):
        print(self)
        self.player_name = name
    def __str__(self):
        return '\n\n\t------ Wizard World -------'
    def make_character(self):
        return Wizard(self.player_name)
    def make_obstacle(self):
        return Ork()
class GameEnvironment:
    def __init__(self, factory):
        self.hero = factory.make_character()
        self.obstacle = factory.make_obstacle()
    def play(self):
        self.hero.interact_with(self.obstacle)
def validate_age(name):
    try:
        age = input('Welcome {}. How old are you? '.format(name))
        age = int(age)
    except ValueError as err:
        print("Age {} is invalid, please try again...".format(age))
        return (False, age)
    return (True, age)

def main():
    name = input("Hello. What's your name? ")
    valid_input = False
    while not valid_input:
        valid_input, age = validate_age(name)
    game = FrogWorld if age < 18 else WizardWorld
    environment = GameEnvironment(game(name))
    environment.play()

if __name__ == '__main__':
    main()

Hy vọng bài viết có ích với bạn. Bạn có thể theo dỏi các bài viết tiếp theo dưới đây. 
Mọi thông tin liên hệ tại MibeSoft

Category: Design Pattern