Skip to main content

Command Palette

Search for a command to run...

Hướng dẫn Factory Pattern trong Java

Published
5 min readView as Markdown

1. Giới thiệu Factory Pattern

Factory Pattern là một mẫu thiết kế thuộc nhóm Creational Patterns, được sử dụng để tạo ra các đối tượng mà không cần chỉ rõ lớp cụ thể của đối tượng đó. Thay vì gọi trực tiếp constructor, Factory Pattern sử dụng một phương thức tạo đối tượng, giúp quản lý và kiểm soát việc khởi tạo dễ dàng hơn.

2. Các trường hợp ứng dụng Factory Pattern

  • Tạo các đối tượng phức tạp: Khi quá trình khởi tạo đối tượng phức tạp hoặc đòi hỏi nhiều bước, Factory Pattern giúp đơn giản hóa quá trình này.

  • Ẩn giấu logic khởi tạo: Giúp ẩn giấu các chi tiết cụ thể về việc tạo đối tượng, chỉ cung cấp một interface chung.

  • Giảm sự phụ thuộc lẫn nhau: Giảm sự phụ thuộc giữa các lớp bằng cách tách biệt quá trình khởi tạo đối tượng ra khỏi lớp sử dụng đối tượng.

3. Triển khai Factory Pattern

3.1. Simple Factory Pattern (Mẫu nhà máy đơn giản)

Trong Simple Factory, một lớp Factory sẽ chịu trách nhiệm tạo ra các đối tượng cụ thể dựa trên các tham số đầu vào.

// Bước 1: Định nghĩa interface hoặc lớp trừu tượng
public interface Shape {
    void draw();
}

// Bước 2: Tạo các lớp cụ thể
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Square");
    }
}

// Bước 3: Tạo lớp Factory để tạo các đối tượng Shape
public class ShapeFactory {
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        return null;
    }
}

// Bước 4: Sử dụng Factory để tạo các đối tượng Shape
public class FactoryPatternDemo {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();

        Shape shape2 = shapeFactory.getShape("SQUARE");
        shape2.draw();
    }
}

3.2. Abstract Factory Pattern (Mẫu nhà máy trừu tượng)

Abstract Factory Pattern mở rộng Simple Factory Pattern bằng cách cung cấp một interface để tạo các nhóm đối tượng liên quan hoặc phụ thuộc mà không cần chỉ rõ các lớp cụ thể của chúng.

// Bước 1: Định nghĩa các interface hoặc lớp trừu tượng
public interface Shape {
    void draw();
}

public interface Color {
    void fill();
}

// Bước 2: Tạo các lớp cụ thể cho Shape
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Square");
    }
}

// Bước 3: Tạo các lớp cụ thể cho Color
public class Red implements Color {
    @Override
    public void fill() {
        System.out.println("Filling with Red");
    }
}

public class Blue implements Color {
    @Override
    public void fill() {
        System.out.println("Filling with Blue");
    }
}

// Bước 4: Tạo các Factory cho Shape và Color
public abstract class AbstractFactory {
    abstract Shape getShape(String shapeType);
    abstract Color getColor(String colorType);
}

public class ShapeFactory extends AbstractFactory {
    @Override
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        return null;
    }

    @Override
    public Color getColor(String colorType) {
        return null; // ShapeFactory không tạo các đối tượng Color
    }
}

public class ColorFactory extends AbstractFactory {
    @Override
    public Shape getShape(String shapeType) {
        return null; // ColorFactory không tạo các đối tượng Shape
    }

    @Override
    public Color getColor(String colorType) {
        if (colorType == null) {
            return null;
        }
        if (colorType.equalsIgnoreCase("RED")) {
            return new Red();
        } else if (colorType.equalsIgnoreCase("BLUE")) {
            return new Blue();
        }
        return null;
    }
}

// Bước 5: Tạo FactoryProducer để tạo AbstractFactory
public class FactoryProducer {
    public static AbstractFactory getFactory(String choice) {
        if (choice.equalsIgnoreCase("SHAPE")) {
            return new ShapeFactory();
        } else if (choice.equalsIgnoreCase("COLOR")) {
            return new ColorFactory();
        }
        return null;
    }
}

// Bước 6: Sử dụng AbstractFactory để tạo các đối tượng
public class AbstractFactoryPatternDemo {
    public static void main(String[] args) {
        AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");

        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();

        Shape shape2 = shapeFactory.getShape("SQUARE");
        shape2.draw();

        AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");

        Color color1 = colorFactory.getColor("RED");
        color1.fill();

        Color color2 = colorFactory.getColor("BLUE");
        color2.fill();
    }
}

4. Phân tích các trường hợp ứng dụng Factory Pattern

4.1. Tạo các đối tượng phức tạp

  • Ưu điểm: Giúp đơn giản hóa quá trình khởi tạo đối tượng bằng cách gom các logic phức tạp vào một nơi duy nhất.

  • Nhược điểm: Có thể dẫn đến sự phụ thuộc vào lớp Factory, cần phải bảo trì và cập nhật khi có thay đổi.

4.2. Ẩn giấu logic khởi tạo

  • Ưu điểm: Giúp ẩn giấu chi tiết cụ thể về việc tạo đối tượng, chỉ cung cấp một interface chung, dễ dàng mở rộng và thay đổi mà không ảnh hưởng đến các lớp sử dụng.

  • Nhược điểm: Cần đảm bảo rằng lớp Factory được thiết kế tốt để không trở nên quá phức tạp.

4.3. Giảm sự phụ thuộc lẫn nhau

  • Ưu điểm: Giảm sự phụ thuộc giữa các lớp bằng cách tách biệt quá trình khởi tạo đối tượng ra khỏi lớp sử dụng đối tượng, giúp mã nguồn dễ bảo trì hơn.

  • Nhược điểm: Cần quản lý và bảo trì các lớp Factory để đảm bảo rằng chúng luôn cập nhật theo các yêu cầu mới.

5. Kết luận

Factory Pattern là một mẫu thiết kế mạnh mẽ và linh hoạt, giúp quản lý và kiểm soát việc tạo các đối tượng trong ứng dụng Java. Việc hiểu và áp dụng đúng Factory Pattern sẽ giúp lập trình viên xây dựng các hệ thống dễ bảo trì, dễ mở rộng và hiệu quả hơn.

More from this blog

hoangkim

366 posts