Nội dung
Factory Method là một mẫu thiết kế khởi tạo giải quyết vấn đề tạo ra các đối tượng mà không chỉ định các lớp cụ thể của chúng. Factory Method định nghĩa một phương thức, phương thức này sẽ được sử dụng để tạo các đối tượng thay vì gọi hàm tạo trực tiếp (toán tử new). Các lớp con có thể ghi đè phương thức này để thay đổi kiểu lớp cho đối tượng sẽ được tạo.
Cách sử dụng mẫu trong C#
Sử dụng: Mẫu Factory Method được sử dụng rộng rãi trong mã C#. Nó rất hữu ích khi bạn cần cung cấp mức độ linh hoạt cao cho mã của mình.
Nhận biết: Các phương thức factory có thể nhận biết bởi các phương thức khởi tạo, phương thức này tạo ra các đối tượng từ các lớp cụ thể, nhưng trả về chúng dưới dạng các đối tượng thuộc kiểu trừu tượng hoặc interface.
Chương trình minh họa
Ví dụ này minh họa cấu trúc của mẫu thiết kế Factory Method. Nó tập trung vào việc trả lời những câu hỏi sau:
- Nó bao gồm những lớp nào?
- Các lớp này có vai trò gì?
- Các thành phần của mẫu có liên quan với nhau theo cách nào?
Program.cs
using System;
namespace DesignPatterns.FactoryMethod.Conceptual
{
// Lớp Creator khai báo phương thức factory method mà sẽ trả về một đối tượng của
// lớp Product. Các lớp con của Creator sẽ cung cấp hiện thực cho phương thức này.
abstract class Creator
{
// Lưu ý Creator cũng có thể tạo một hiện thực mặc định cho phương thức factory.
public abstract IProduct FactoryMethod();
// Cũng lưu ý rằng, mặc dù tên của nó, nhưng trách nhiệm chỉnh của Creator không phải
// là tạo product. Thông thường, nó chứa những logic cốt lõi dựa trên đối tượng Product,
// được trả về bởi phương thức factory. Các lớp con có thể thay đổi logic này không
// trực tiếp bằng cách ghi đè phương thức factory và trả về một kiểu khác của product.
public string SomeOperation()
{
// Gọi phương thức factory để tạo một đối tượng Product.
var product = FactoryMethod();
// Giờ thì sử dụng product.
var result = "Creator: The same creator's code has just worked with "
+ product.Operation();
return result;
}
}
// Concrete Creator ghi đè phương thức factory để thay đổi kiểu trả về của product.
class ConcreteCreator1 : Creator
{
// Lưu ý rằng chữ ký của phương thức vẫn sử dụng kiểu trừu tượng, mặc dù kiểu
// product cụ thể thực sự được trả về từ phương thức. Bằng cách này, Creator có
// thể độc lập với các lớp product cụ thể.
public override IProduct FactoryMethod()
{
return new ConcreteProduct1();
}
}
class ConcreteCreator2 : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProduct2();
}
}
// Interface Product khai báo các phương thức mà tất cả các concrete product
// phải hiện thực.
public interface IProduct
{
string Operation();
}
// Concrete Product cung cấp các hiện thực khác nhau của interface Product.
class ConcreteProduct1 : IProduct
{
public string Operation()
{
return "{Result of ConcreteProduct1}";
}
}
class ConcreteProduct2 : IProduct
{
public string Operation()
{
return "{Result of ConcreteProduct2}";
}
}
class Client
{
public void Main()
{
Console.WriteLine("App: Launched with the ConcreteCreator1.");
ClientCode(new ConcreteCreator1());
Console.WriteLine("");
Console.WriteLine("App: Launched with the ConcreteCreator2.");
ClientCode(new ConcreteCreator2());
}
// Client làm việc với một thể hiện của concrete creator, mặc dù thông qua interface
// cơ sở của nó. Miễn là client còn tiếp tục làm việc với creator thông qua interface
// cơ sở, bạn có thể truyền nó vào bất kỳ lớp con nào của creator.
public void ClientCode(Creator creator)
{
// ...
Console.WriteLine("Client: I'm not aware of the creator's class," +
"but it still works.\n" + creator.SomeOperation());
// ...
}
}
class Program
{
static void Main(string[] args)
{
new Client().Main();
}
}
}
Kết quả
App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
Để lại một bình luận