Tại thời điểm này, có lẽ bạn đã bắt gặp các mẫu thiết kế. Ví dụ: đơn lẻ .

Hãy nhớ lại các mẫu là gì, tại sao chúng lại cần thiết và các mẫu sáng tạo là gì (singleton là một ví dụ). Chúng ta cũng sẽ nghiên cứu một mô hình mới: phương pháp xuất xưởng.

Trong phát triển phần mềm, một mẫu thiết kế là một cấu trúc kiến ​​trúc có thể lặp lại, đại diện cho một giải pháp cho một vấn đề thiết kế trong một số ngữ cảnh định kỳ.

Thông thường, một mẫu không phải là giải pháp cuối cùng có thể được chuyển đổi trực tiếp thành mã. Nó chỉ là một giải pháp mẫu cho một vấn đề có thể được sử dụng trong các tình huống khác nhau.

Các mẫu sáng tạo là các mẫu thiết kế xử lý quá trình tạo đối tượng. Chúng giúp tạo ra một hệ thống độc lập với phương pháp được sử dụng để tạo, sắp xếp và trình bày các đối tượng.

Phương thức xuất xưởng là một mẫu thiết kế sáng tạo xác định một giao diện chung để tạo các đối tượng trong lớp cha, mang lại cho lớp con của nó khả năng tạo các đối tượng này. Tại thời điểm tạo, con cháu có thể xác định lớp nào sẽ tạo.

Mô hình giải quyết vấn đề gì?

Hãy tưởng tượng rằng bạn quyết định tạo một chương trình giao hàng. Ban đầu, bạn sẽ thuê người đưa thư bằng ô tô và sử dụng mộtXe hơiđối tượng để đại diện cho một chiếc xe giao hàng trong chương trình. Người chuyển phát giao các gói hàng từ điểm A đến điểm B, v.v. Dễ như ăn bánh.

Chương trình đang trở nên phổ biến. Doanh nghiệp của bạn đang phát triển và bạn muốn mở rộng sang các thị trường mới. Ví dụ: bạn cũng có thể bắt đầu giao đồ ăn và vận chuyển hàng hóa. Trong trường hợp này, thực phẩm có thể được giao bằng cách đi bộ, xe tay ga và xe đạp, nhưng xe tải là cần thiết để vận chuyển hàng hóa.

Bây giờ bạn cần theo dõi một số điều (khi nào, giao cho ai, cái gì và số lượng bao nhiêu), bao gồm cả số lượng mà mỗi người chuyển phát có thể mang theo. Các phương thức vận tải mới có tốc độ và năng lực khác nhau. Sau đó, bạn nhận thấy rằng hầu hết các thực thể trong chương trình của bạn được liên kết chặt chẽ vớiXe hơilớp học. Bạn nhận ra rằng để làm cho chương trình của mình hoạt động với các phương thức phân phối khác, bạn sẽ phải viết lại cơ sở mã hiện có và thực hiện lại điều đó mỗi khi bạn thêm một phương tiện mới.

Kết quả là mã khủng khiếp chứa đầy các câu lệnh có điều kiện thực hiện các hành động khác nhau tùy thuộc vào loại phương tiện giao thông.

Giải pháp

Mẫu phương thức xuất xưởng gợi ý tạo các đối tượng bằng cách gọi một phương thức xuất xưởng đặc biệt thay vì trực tiếp sử dụng toán tử mới . Các lớp con của lớp có phương thức xuất xưởng có thể sửa đổi các đối tượng đã tạo của các phương tiện cụ thể. Thoạt nhìn, điều này có vẻ vô nghĩa: chúng ta chỉ đơn giản là di chuyển lệnh gọi hàm tạo từ vị trí này sang vị trí khác trong chương trình. Nhưng giờ đây, bạn có thể ghi đè phương thức xuất xưởng trong một lớp con để thay đổi kiểu vận chuyển đang được tạo.

Hãy xem sơ đồ lớp cho cách tiếp cận này:

Để hệ thống này hoạt động, tất cả các đối tượng được trả về phải có một giao diện chung. Các lớp con sẽ có thể tạo ra các đối tượng của các lớp khác nhau thực hiện giao diện này.

Ví dụ: các lớp Xe tảiXe hơi triển khai giao diện CourierTransport với một phương thức phân phối . Mỗi lớp này thực hiện phương pháp theo một cách khác nhau: xe tải vận chuyển hàng hóa, trong khi ô tô vận chuyển thực phẩm, gói hàng, v.v. Phương thức xuất xưởng trong lớp TruckCreator trả về một đối tượng xe tải và lớp CarCreator trả về một đối tượng xe hơi.

Đối với máy khách của phương thức xuất xưởng, không có sự khác biệt giữa các đối tượng này, vì nó sẽ coi chúng như một loại CourierTransport trừu tượng nào đó . Khách hàng sẽ quan tâm sâu sắc rằng đối tượng có một phương pháp để phân phối, nhưng phương pháp đó hoạt động chính xác như thế nào không quan trọng.

Thực hiện trong Java:


public interface CourierTransport {
	void deliver();
}
public class Car implements CourierTransport {
	@Override
	public void deliver() {
    		System.out.println("The package is being delivered by car");
	}
}
public class Truck implements CourierTransport {
	@Override
	public void deliver() {
    		System.out.println("The freight is being delivered by truck");
	}
}
public abstract class CourierTransportCreator {
	public abstract CourierTransport createTransport();
}
public class CarCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Car();
	}
}
public class TruckCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Truck();
	}
}
 
public class Delivery {
	private String address;
	private CourierTransport courierTransport;
 
	public void Delivery() {
	}
 
	public Delivery(String address, CourierTransport courierTransport) {
    	this.address = address;
    	this.courierTransport = courierTransport;
	}
 
	public CourierTransport getCourierTransport() {
    		return courierTransport;
	}
 
	public void setCourierTransport(CourierTransport courierTransport) {
    		this.courierTransport = courierTransport;
	}
 
	public String getAddress() {
    		return address;
	}
 
	public void setAddress(String address) {
    		this.address = address;
	}
}
public static void main(String[] args) {
    	// Accept a new type of order from the database (pseudocode)
    	String type = database.getTypeOfDeliver();
 
    	Delivery delivery = new Delivery();
    	
    	// Set the transport for delivery
        delivery.setCourierTransport(getCourierTransportByType(type));
    	
    	// Make the delivery
        delivery.getCourierTransport().deliver();
 
	}
 
	public static CourierTransport getCourierTransportByType(String type) {
    	switch (type) {
        	case "CarDelivery":
            	return new CarCreator().createTransport();
        	case "TruckDelivery":
            	return new TruckCreator().createTransport();
        	default:
            	throw new RuntimeException();
	    }
	}
    

Nếu chúng ta muốn tạo một đối tượng vận chuyển mới thì chương trình sẽ tự động tạo một đối tượng vận chuyển phù hợp.

Khi nào chúng ta nên áp dụng mô hình này?

1. Khi bạn không biết trước các loại và sự phụ thuộc của các đối tượng mà mã của bạn cần làm việc.

Phương pháp xuất xưởng tách mã để sản xuất các hình thức vận chuyển khỏi mã sử dụng phương tiện vận chuyển. Do đó, mã để tạo đối tượng có thể được mở rộng mà không cần chạm vào phần còn lại của mã.

Ví dụ: để thêm hỗ trợ cho một loại phương tiện vận chuyển mới, bạn cần tạo một lớp con mới và xác định một phương thức xuất xưởng trong đó trả về một thể hiện của phương tiện vận chuyển mới.

2. Khi bạn muốn tiết kiệm tài nguyên hệ thống bằng cách sử dụng lại các đối tượng hiện có thay vì tạo mới.

Sự cố này thường xảy ra khi làm việc với các đối tượng sử dụng nhiều tài nguyên, chẳng hạn như kết nối cơ sở dữ liệu, hệ thống tệp, v.v.

Hãy nghĩ về các bước bạn cần thực hiện để tái sử dụng các đối tượng hiện có:

  1. Trước tiên, bạn cần tạo một kho lưu trữ dùng chung để lưu trữ tất cả các đối tượng mà bạn tạo.

  2. Khi yêu cầu một đối tượng mới, bạn cần tìm trong kho lưu trữ và kiểm tra xem nó có chứa đối tượng khả dụng hay không.

  3. Trả đối tượng về mã khách hàng.

  4. Nhưng nếu không có đối tượng nào, hãy tạo một đối tượng mới và thêm nó vào kho lưu trữ.

Tất cả mã này cần được đặt ở đâu đó không làm lộn xộn mã máy khách. Nơi thuận tiện nhất sẽ là hàm tạo, vì chúng ta chỉ cần tất cả các kiểm tra này khi tạo đối tượng. Than ôi, một hàm tạo luôn tạo một đối tượng mới — nó không thể trả về một đối tượng hiện có.

Điều đó có nghĩa là cần có một phương thức khác có thể trả về cả đối tượng hiện có và đối tượng mới. Đây sẽ là phương pháp xuất xưởng.

3. Khi bạn muốn cho phép người dùng mở rộng các phần của khung hoặc thư viện của bạn.

Người dùng có thể mở rộng các lớp khung của bạn thông qua kế thừa. Nhưng làm thế nào để bạn làm cho khung tạo các đối tượng của các lớp mới này thay vì các lớp tiêu chuẩn?

Giải pháp là cho phép người dùng mở rộng không chỉ các thành phần mà còn cả các lớp tạo ra các thành phần đó. Và đối với điều này, các lớp tạo phải có các phương thức tạo cụ thể có thể được xác định.

Thuận lợi

  • Tách một lớp khỏi các lớp vận chuyển cụ thể.
  • Giữ mã để tạo các hình thức vận chuyển ở một nơi, giúp mã dễ bảo trì hơn.
  • Đơn giản hóa việc bổ sung các phương thức vận chuyển mới vào chương trình.
  • Thực hiện nguyên tắc đóng mở.

Nhược điểm

Có thể dẫn đến hệ thống phân cấp lớp song song lớn, vì mỗi lớp sản phẩm phải có lớp con người tạo riêng.

Hãy tóm tắt

Bạn đã tìm hiểu về mẫu phương thức xuất xưởng và thấy một triển khai khả thi. Mẫu này thường được sử dụng trong các thư viện khác nhau cung cấp các đối tượng để tạo các đối tượng khác.

Sử dụng mẫu phương thức xuất xưởng khi bạn muốn dễ dàng thêm các đối tượng mới của các lớp con của các lớp hiện có để tương tác với logic nghiệp vụ chính của bạn và không làm phình mã của bạn do các ngữ cảnh khác nhau.