[DesignPattern] Simple Factory Pattern

by chungnt6
599 views

Background

Hầu hết anh em developer đều đã nghe qua về Design Pattern

Tuy nhiên mình thấy còn nhiều người (gồm cả mình) đều không có kinh nghiêm áp dụng nó.

Nên mình lập topic về design pattern để mọi người có thể chia sẻ kinh nghiệm và cách áp dụng nó trong các bài toán cụ thể.

Vậy đầu tiên chúng ta phải hiểu design pattern là gì?

  • Theo mình hiểu design pattern đơn giản là các giải pháp mẫu tối ưu cho từng tình huống cụ thể trong lập trình OOP.

Taị sao lại sử dụng design pattern?

Một thực tế là mình nghe rất nhiều câu như refactor đi (dm code như shit, fucking coding …),đập hết đi xây lại.

Tại sao chúng ta lại muốn như thế?

Vì hầu hết các source code ban đầu đều rất khó maintain và mở rộng, nên khi có một yêu cầu mới hay một bug,

anh em lại cặm cụi sửa code, sửa bug này lại sinh ra bug khác nên effort để giải quyết một vấn đề rất tốn kém.

Do đó nếu mình không chỉ "code để chạy được" mà suy nghĩ, áp dụng các design pattern trươc khi viết ra

sẽ rút ngắn phần lớn thời gian development và maintain.

Sau đây mình xin trình bầy một số design pattern mà mình đã đọc qua.

Đầu tiên mình xin tập trung vào một loại pattern mà chắc anh em ai cũng nghe qua, đó là Factory Pattern

Factory Pattern có 3 loại: Simple factory, Factory method và Abstract Factory

Bài lần này mình sẽ trình bày về Simple Factory Pattern

Simple Factory Pattern

Bài toán

Nào chúng ta hãy làm quen với Simple Factory Pattern với một ví dụ như sau:

Giả sử bạn đang viết chương trình đặt hàng và ship hàng cho một cửa hàng Pizza

Quá trình đặt hàng một chiếc Pizza sẽ qua các công đoạn như chuẩn bị (prepare), nướng (bake) và đóng hộp (box)

Xử lý để chạy được & vấn đề

Chương trình có thể được viết như sau

Class PizzaStore {
  public Pizza orderPizza() {
    Pizza pizza = new Pizza();
    pizza.prepare();
    pizza.bake();
    pizza.box();
    return pizza;
  }
  public void shipPizza() {
    Pizza pizza = new Pizza();
    pizza.ship();
   }
}

OK như vậy là có sample về chương trình orderPizza và shipPizza.

Nhưng chủ cửa hàng lại muốn có nhiều món pizza cơ mà.

Ví du: Pizza gà (ChickenPizza), Pizza phô mai(CheesePizza)

Bạn nên làm thế nào ???

Dễ mà tạo một lớp cha Pizza và create 2 lớp con là ChickenPizza và CheesePizza

Sau đó add thêm parameter type cho orderPizza và shipPizza

Class PizzaStore {
  public Pizza orderPizza(String type) {
    Pizza pizza;
    if ("chicken".equals(type) {
      pizza = new ChickenPizza();
    } esle ("cheese".equals(type) {
      pizza = new ChickenPizza();
    }
    pizza.prepare();
    pizza.bake();
    pizza.box();
    return pizza;
  }
  public void shipPizza(String type) {
    Pizza pizza;
    if ("chicken".equals(type) {
      pizza = new ChickenPizza();
    } esle if ("cheese".equals(type) {
      pizza = new ChickenPizza();
    }
    pizza.ship();
  }
}

OK các bạn thấy thế nào, chương trình chạy ngon không có lỗi gì luôn :D.

Một tuần sau cửa hàng thấy cần thêm món Pizza hải sản (SeaFoodPizza) để tăng thêm khách hàng

Bạn sẽ vào sửa method orderPizza???

Class PizzaStore {
  public Pizza orderPizza(String type) {
    Pizza pizza;
    if ("chicken".equals(type) {
      pizza = new ChickenPizza();
    } esle if ("cheese".equals(type) {
      pizza = new ChickenPizza();
    } else if ("seafood".equals(type) {
      pizza = new SeaFoodPizza();
    }
    pizza.prepare();
    pizza.bake();
    pizza.box();
  }
  public void shipPizza(String type) {
    Pizza pizza;
    if ("chicken".equals(type) {
      pizza = new ChickenPizza();
    } esle if ("cheese".equals(type) {
      pizza = new ChickenPizza();
    }
    pizza.ship();
  }
}

Cơn ác mộng mới chỉ bắt đầu :)). Đấy là mình chỉ liệt kê 2 chức năng cơ bản, điều gì sẽ xảy ra nếu còn rất nhiều chức năng khác cần lấy thông tin pizza theo từng loại

Ví du: Lấy thông tin giá, tên, … của từng loại Pizza

Bạn sẽ phải hì hục sửa code tất cả cả các method đấy nếu cửa hàng tạo thêm một loại Pizza.

Vâng bạn sẽ vẫn cố gắng sửa để nó có thể chạy được nhưng bạn sẽ tốn rất nhiều effort để làm việc này nếu có hàng chục method cần sửa.

Bạn cũng lo lắng mình có thể quên xử lý ở một method nào đấy,…

-> Giờ bạn đã sợ maintain chưa

Áp dụng Simple Factory Pattern vào bài toán

Quá nhiều điều để lo lắng chúng ta phải refactor thôi.

Đầu tiên chắc các bạn cũng thấy luôn, chúng ta cần đóng gói việc khởi tạo object bên dưới

if ("chicken".equals(type) {
  pizza = new ChickenPizza();
} esle if ("cheese".equals(type) {
  pizza = new ChickenPizza();
} else if ("seafood".equals(type) {
  pizza = new SeaFoodPizza();
}

Chuyển đoạn code trên sang một class factory

Class SimplePizzaFactory {
  public Pizza createPizza(type) {
    Pizza pizza;
    if ("chicken".equals(type) {
      pizza = new ChickenPizza();
    } esle if ("cheese".equals(type) {
      pizza = new ChickenPizza();
    } else if ("seafood".equals(type) {
      pizza = new SeaFoodPizza();
    }
    return pizza;
 }
}

Tiếp theo chúng ta sẽ sử dụng SimplePizzaFactory để tạo trong PizzaStore để tạo các object

Class PizzaStore {
  SimplePizzaFactory mFactory;

  public PizzaStore (SimplePizzaFactory factory) {
    mFactory = factory;
  }

  public Pizza orderPizza(String type) {
    Pizza pizza = mFactory.createPizza(type);
    pizza.prepare();
    pizza.bake();
    pizza.box();
  }
  public void shipPizza(String type) {
    Pizza pizza = mFactory.createPizza(type);
    pizza.ship();
  }
}

Bạn thấy công việc đơn giản hơn chưa, việc khởi tạo object cần thiết được xử lý trong Factory

Như vậy chúng ta không cần phải lo lắng sửa code ở từng method như orderPizzahay shipPizza, … nữa 🙂

Conlution

Đây chỉ là một ví dụ rất cơ bản về Design Pattern giúp mọi người dễ hình dung và tiếp cận

Chúng ta còn rất nhiều bài toán phức tạp khác cần Design Pattern để xử lý

Quan trọng mọi người hiểu được việc "code để chạy" có thể nhanh trong thời điểm đấy

Tuy nhiên việc mọi người phải rework để phát triển nó sẽ tốn gấp đôi gấp mười lần effort nếu mọi người có thể làm Design cẩn thận từ đầu

Do đó việc hiểu các Design pattern hỗ trợ rất tốt cho mọi người trong việc triển khai các bài toán cụ thể

Hy vọng bài này giúp mọi người hiểu được cơ bản Design Pattern là gì và tầm quan trọng của nó trong software

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

You may also like