Creational Patterns
Creational patterns tập trung vào việc khởi tạo objects, giúp tách biệt quá trình khởi tạo khỏi logic nghiệp vụ và tạo objects một cách linh hoạt hơn.
1. Singleton Pattern
Mục đích: Đảm bảo một class chỉ có một instance duy nhất và cung cấp global access point đến instance đó.
C# Implementation
public sealed class Singleton
{
private static readonly Lazy<Singleton> _instance =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance => _instance.Value;
private Singleton()
{
// Private constructor prevents instantiation
}
}
Use Cases
- Database connections
- Logging services
- Configuration managers
- Caching services
Considerations
- Thread-safety với
Lazy<T> - Consider DI container thay vì Singleton
- IDisposable nếu cần cleanup resources
2. Factory Method Pattern
Mục đích: Định nghĩa interface để tạo object, nhưng để subclasses quyết định class nào sẽ được khởi tạo.
C# Implementation
public interface IProduct
{
string Operation();
}
public abstract class Creator
{
public abstract IProduct FactoryMethod();
public string SomeOperation()
{
var product = FactoryMethod();
return product.Operation();
}
}
public class ConcreteProductA : IProduct
{
public string Operation() => "Result of ConcreteProductA";
}
public class ConcreteCreatorA : Creator
{
public override IProduct FactoryMethod() => new ConcreteProductA();
}
Use Cases
- UI frameworks (create different controls)
- Document generators (PDF, Word, etc.)
- Payment processors
3. Abstract Factory Pattern
Mục đích: Tạo families of related objects mà không cần specify concrete classes.
C# Implementation
public interface IButton
{
void Render();
}
public interface ICheckbox
{
void Render();
}
// Abstract Factory
public interface IUIFactory
{
IButton CreateButton();
ICheckbox CreateCheckbox();
}
public class WindowsFactory : IUIFactory
{
public IButton CreateButton() => new WindowsButton();
public ICheckbox CreateCheckbox() => new WindowsCheckbox();
}
public class MacFactory : IUIFactory
{
public IButton CreateButton() => new MacButton();
public ICheckbox CreateCheckbox() => new MacCheckbox();
}
Use Cases
- Cross-platform applications
- Theme systems
- Database abstraction (SQL Server, PostgreSQL, etc.)
4. Builder Pattern
Mục đích: Tách biệt construction của complex object khỏi representation, cho phép tạo different representations.
C# Implementation
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
public class PersonBuilder
{
private readonly Person _person = new Person();
public PersonBuilder WithName(string name)
{
_person.Name = name;
return this;
}
public PersonBuilder WithAge(int age)
{
_person.Age = age;
return this;
}
public PersonBuilder WithAddress(string address)
{
_person.Address = address;
return this;
}
public Person Build() => _person;
}
// Usage
var person = new PersonBuilder()
.WithName("John")
.WithAge(30)
.WithAddress("123 Main St")
.Build();
Use Cases
- Building complex objects (SQL queries, HTTP requests)
- Immutable objects
- Fluent APIs
- Object with many optional parameters
5. Prototype Pattern
Mục đích: Tạo new objects bằng cách cloning một existing object (prototype).
C# Implementation
public interface IPrototype<T>
{
T Clone();
}
public class Person : IPrototype<Person>
{
public string Name { get; set; }
public Address Address { get; set; }
public Person Clone()
{
// Shallow copy
return (Person)this.MemberwiseClone();
// Or deep copy
return new Person
{
Name = this.Name,
Address = new Address
{
Street = this.Address.Street,
City = this.Address.City
}
};
}
}
Use Cases
- Complex object creation that’s expensive
- Object caching
- Avoiding subclassing
Comparison
| Pattern | Purpose | Complexity |
|---|---|---|
| Singleton | Single instance | Low |
| Factory Method | Subclass decides | Medium |
| Abstract Factory | Families of objects | High |
| Builder | Complex construction | Medium |
| Prototype | Cloning objects | Low-Medium |
Best Practices
- Chọn đúng pattern: Cân nhắc requirements trước khi áp dụng
- Prefer Composition over Inheritance: Builder và Factory thường tốt hơn inheritance
- Consider DI Containers: Trong modern .NET, DI thường replace Singleton pattern
- Immutability: Sử dụng Builder cho immutable objects
- Thread Safety: Đặc biệt quan trọng với Singleton trong multi-threaded applications