Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

PatternPurposeComplexity
SingletonSingle instanceLow
Factory MethodSubclass decidesMedium
Abstract FactoryFamilies of objectsHigh
BuilderComplex constructionMedium
PrototypeCloning objectsLow-Medium

Best Practices

  1. Chọn đúng pattern: Cân nhắc requirements trước khi áp dụng
  2. Prefer Composition over Inheritance: Builder và Factory thường tốt hơn inheritance
  3. Consider DI Containers: Trong modern .NET, DI thường replace Singleton pattern
  4. Immutability: Sử dụng Builder cho immutable objects
  5. Thread Safety: Đặc biệt quan trọng với Singleton trong multi-threaded applications