Trước tiên, chúng ta hãy cùng cafedev giới thiệu mọi thứ về Prototype Design Pattern và phần code ví dụ chi tiết nhằm giúp ace dễ hiểu khi áp dụng trên các ngôn ngữ khác nhau. Ace có thể tham khảo thêm các bài khác tại series Design Pattern tại đây.

Nguyên mẫu(Prototype) cho phép chúng ta che giấu sự phức tạp của việc tạo các phiên bản mới từ máy khách(client). Khái niệm này là sao chép một đối tượng hiện có thay vì tạo một instance mới từ đầu, một cái gì đó có thể bao gồm các hoạt động tốn kém. Đối tượng hiện có hoạt động như một nguyên mẫu(Prototype) và chứa trạng thái của đối tượng. Đối tượng mới được sao chép chỉ có thể thay đổi các thuộc tính tương tự nếu được yêu cầu. Cách tiếp cận này giúp tiết kiệm tài nguyên và thời gian tốn kém, đặc biệt khi việc tạo đối tượng là một quá trình nặng nhọc.

The prototype pattern(Prototype) là một  . Các Prototype patterns là bắt buộc, khi việc tạo đối tượng tốn thời gian và thao tác tốn kém, vì vậy chúng ta tạo đối tượng bằng chính đối tượng hiện có. Một trong những cách tốt nhất hiện có để tạo đối tượng từ các đối tượng hiện có là phương thức clone() . Nhân bản là cách tiếp cận đơn giản nhất để thực hiện Prototype patterns. Tuy nhiên, bạn phải quyết định cách sao chép đối tượng hiện có dựa trên mô hình kinh doanh của mình.

1. Các thành phần tham gia Prototype patterns

1) Nguyên mẫu(Prototype) : Đây là nguyên mẫu(Prototype) của đối tượng thực tế.

2) Đăng ký nguyên mẫu(Prototype registry): Đây được sử dụng làm dịch vụ đăng ký để có thể truy cập tất cả các nguyên mẫu(Prototype) bằng các tham số chuỗi đơn giản.

3) Máy khách(Client): Máy khách sẽ chịu trách nhiệm sử dụng dịch vụ đăng ký để truy cập các instance Prototype.

2. Khi nào sử dụng Prototype Design Pattern

Khi nào một hệ thống phải độc lập với cách các sản phẩm của nó được tạo, cấu tạo và đại diện và Khi nào các lớp cần khởi tạo được chỉ định tại thời điểm chạy.

Ví dụ:

1) Bằng cách tải động hoặc Để tránh xây dựng hệ thống phân cấp lớp của các nhà máy song song với hệ thống phân cấp lớp của sản phẩm hoặc

2) Khi các thể hiện của một lớp chỉ có thể có một trong một số kết hợp trạng thái khác nhau. Có thể thuận tiện hơn khi cài đặt một số lượng nguyên mẫu tương ứng và sao chép chúng hơn là khởi tạo lớp theo cách thủ công, mỗi lần với trạng thái thích hợp.

3. Sơ đồ UML của Mẫu thiết kế Nguyên mẫu(Prototype)

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

// A Java program to demonstrate working of 
// Prototype Design Pattern with example  
// of a ColorStore class to store existing objects. 
  
import java.util.HashMap; 
import java.util.Map; 
  
  
abstract class Color implements Cloneable 
{ 
      
    protected String colorName; 
       
    abstract void addColor(); 
       
    public Object clone() 
    { 
        Object clone = null; 
        try 
        { 
            clone = super.clone(); 
        }  
        catch (CloneNotSupportedException e)  
        { 
            e.printStackTrace(); 
        } 
        return clone; 
    } 
} 
  
class blueColor extends Color 
{ 
    public blueColor()  
    { 
        this.colorName = "blue"; 
    } 
   
    @Override
    void addColor()  
    { 
        System.out.println("Blue color added"); 
    } 
      
} 
  
class blackColor extends Color{ 
   
    public blackColor() 
    { 
        this.colorName = "black"; 
    } 
   
    @Override
    void addColor()  
    { 
        System.out.println("Black color added"); 
    } 
} 
   
class ColorStore { 
   
    private static Map<String, Color> colorMap = new HashMap<String, Color>();  
       
    static 
    { 
        colorMap.put("blue", new blueColor()); 
        colorMap.put("black", new blackColor()); 
    } 
       
    public static Color getColor(String colorName) 
    { 
        return (Color) colorMap.get(colorName).clone(); 
    } 
} 
  
  
// Driver class 
class Prototype 
{ 
    public static void main (String[] args) 
    { 
        ColorStore.getColor("blue").addColor(); 
        ColorStore.getColor("black").addColor(); 
        ColorStore.getColor("black").addColor(); 
        ColorStore.getColor("blue").addColor(); 
    } 
} 

Đầu ra:

Blue color added
Black color added
Black color added
Blue color added

Sơ đồ UML của ví dụ:

4. Ưu điểm của Prototype Design Pattern

  • Thêm và xóa sản phẩm trong thời gian chạy – Nguyên mẫu cho phép bạn kết hợp một lớp sản phẩm cụ thể mới vào hệ thống chỉ bằng cách đăng ký một phiên bản nguyên mẫu với khách hàng. Điều đó linh hoạt hơn một chút so với các mẫu sáng tạo khác, bởi vì khách hàng có thể cài đặt và gỡ bỏ các nguyên mẫu trong thời gian chạy.
  • Chỉ định các đối tượng mới bằng các giá trị khác nhau – Các hệ thống năng động cao cho phép bạn xác định hành vi mới thông qua thành phần đối tượng bằng cách chỉ định giá trị cho các biến của đối tượng chứ không phải bằng cách xác định các lớp mới.
  • Chỉ định các đối tượng mới theo cấu trúc khác nhau – Nhiều ứng dụng xây dựng các đối tượng từ các bộ phận và phần con. Để thuận tiện, các ứng dụng như vậy thường cho phép bạn khởi tạo các cấu trúc phức tạp, do người dùng xác định để sử dụng lặp lại một mạch con cụ thể.
  • Giảm bớt phân lớp – Phương pháp Nhà máy thường tạo ra một hệ thống phân cấp các lớp của Người tạo song song với hệ thống phân cấp lớp sản phẩm. Mẫu Prototype cho phép bạn sao chép một nguyên mẫu thay vì yêu cầu một phương pháp gốc để tạo một đối tượng mới. Do đó, bạn hoàn toàn không cần phân cấp lớp Người sáng tạo.

5. Nhược điểm của  Prototype Design Pattern

  • Quá mức cần thiết cho một dự án sử dụng rất ít đối tượng và / hoặc không có trọng tâm cơ bản về việc mở rộng chuỗi nguyên mẫu.
  • Nó cũng ẩn các lớp sản phẩm cụ thể khỏi khách hàng
  • Mỗi lớp con của Nguyên mẫu phải triển khai hoạt động clone () có thể khó, khi các lớp đang được xem xét đã tồn tại. Ngoài ra việc triển khai clone() cũng có thể khó khăn khi bên trong của chúng bao gồm các đối tượng không hỗ trợ sao chép hoặc có các tham chiếu vòng tròn.

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!