GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Design pattern Creational Pattern Hướng dẫn Java Design Pattern – Abstract Factory

Hướng dẫn Java Design Pattern – Abstract Factory

Đăng vào 15/09/2018 . Được đăng bởi GP Coder . 61900 Lượt xem . Toàn màn hình

Trong bài trước chúng ta đã tìm hiểu về Factory Method Pattern. Trong bài này chúng ta tiếp tục tìm hiểu một Pattern khác trong nhóm Creational Design Pattern là Abstract Factory Design Pattern.

Nội dung

  • 1 Abstract Factory Pattern là gì?
  • 2 Cài đặt Abstract Factory Pattern như thế nào?
  • 3 Lợi ích của Abstract Factory Pattern là gì?

Abstract Factory Pattern là gì?

Abstract Factory is a creational design pattern that provide an interface for creating families of  related or dependent objects without specifying their concrete classes.

Abstract Factory pattern là một trong những Creational pattern. Nó là phương pháp tạo ra một Super-factory dùng để tạo ra các Factory khác. Hay còn được gọi là Factory của các Factory. Abstract Factory Pattern là một Pattern cấp cao hơn so với Factory Method Pattern.

Trong Abstract Factory pattern, một interface có nhiệm vụ tạo ra một Factory của các object có liên quan tới nhau mà không cần phải chỉ ra trực tiếp các class của object. Mỗi Factory được tạo ra có thể tạo ra các object bằng phương pháp giống như Factory pattern.

Hãy tưởng tượng, Abstract factory như là một nhà máy lớn chứa nhiều nhà máy nhỏ, trong các nhà máy đó có những xưởng sản xuất, các xưởng đó tạo ra những sản phẩm khác nhau.

Cài đặt Abstract Factory Pattern như thế nào?

Một Abstract Factory Pattern bao gồm các thành phần cơ bản sau:

  • AbstractFactory: Khai báo dạng interface hoặc abstract class chứa các phương thức để tạo ra các đối tượng abstract.
  • ConcreteFactory: Xây dựng, cài đặt các phương thức tạo các đối tượng cụ thể.
  • AbstractProduct: Khai báo dạng interface hoặc abstract class để định nghĩa đối tượng abstract.
  • Product: Cài đặt của các đối tượng cụ thể, cài đặt các phương thức được quy định tại AbstractProduct.
  • Client: là đối tượng sử dụng AbstractFactory và các AbstractProduct.

Ví dụ: Một công ty đồ nội thất chuyên sản xuất ghế (Chair): ghế nhựa (PlasticChair) và ghế gỗ (WoodChair). Với tình hình kinh doanh ngày càng thuận thợi nên công ty quyết định mở rộng thêm sản xuất bàn (Table). Với lợi thế là đã có kinh nghiệm từ sản xuất ghế nên công ty vẫn giữ chất liệu là nhựa (PlasticTable) và gỗ (WoodTable) cho sản xuất bàn. Tuy nhiên, quy trình sản xuất ghế/ bàn theo từng chất liệu (MaterialType) là khác nhau. Nên công ty tách ra là nhà máy (Factory): 1 cho sản xuất vật liệu bằng nhựa (PlasticFactory), 1 cho sản xuất vật liệu bằng gỗ (WoodFactory), nhưng cả 2 đều có thể sản xuất ghế và bàn (FunitureAbstractFactory). Khi khách hàng cần mua một món đồ nào, khách hàng (Client) chỉ cần đến cửa hàng để mua (FunitureFactory). Khi đó ứng với từng hàng hóa và vật liệu sẽ được chuyển về phân xưởng tương ứng để sản xuất (createXXX) ra bàn (Table) và ghế (Chair).

Hệ thống được minh họa như sau:

Chương trình được cài đặt theo Abstract Factory Pattern như sau:

Super Factory Class:


package com.gpcoder.patterns.creational.abstractfactory.factory;

import com.gpcoder.patterns.creational.abstractfactory.MaterialType;
import com.gpcoder.patterns.creational.abstractfactory.factory.impl.FlasticFactory;
import com.gpcoder.patterns.creational.abstractfactory.factory.impl.WoodFactory;

public class FurnitureFactory {

	private FurnitureFactory() {

	}

	// Returns a concrete factory object that is an instance of the
	// concrete factory class appropriate for the given architecture.
	public static FurnitureAbstractFactory getFactory(MaterialType materialType) {
		switch (materialType) {
		case FLASTIC:
			return new FlasticFactory();
		case WOOD:
			return new WoodFactory();
		default:
			throw new UnsupportedOperationException("This furniture is unsupported ");
		}
	}
}

AbstractFactory:


package com.gpcoder.patterns.creational.abstractfactory.factory;

import com.gpcoder.patterns.creational.abstractfactory.chair.Chair;
import com.gpcoder.patterns.creational.abstractfactory.table.Table;

public abstract class FurnitureAbstractFactory {

	public abstract Chair createChair();

	public abstract Table createTable();
	
}

ConcreteFactory:

FlasticFactory:


package com.gpcoder.patterns.creational.abstractfactory.factory.impl;

import com.gpcoder.patterns.creational.abstractfactory.chair.Chair;
import com.gpcoder.patterns.creational.abstractfactory.chair.PlasticChair;
import com.gpcoder.patterns.creational.abstractfactory.factory.FurnitureAbstractFactory;
import com.gpcoder.patterns.creational.abstractfactory.table.PlasticTable;
import com.gpcoder.patterns.creational.abstractfactory.table.Table;

public class FlasticFactory extends FurnitureAbstractFactory {

	@Override
	public Chair createChair() {
		return new PlasticChair();
	}

	@Override
	public Table createTable() {
		return new PlasticTable();
	}

}

WoodFactory:


package com.gpcoder.patterns.creational.abstractfactory.factory.impl;

import com.gpcoder.patterns.creational.abstractfactory.chair.Chair;
import com.gpcoder.patterns.creational.abstractfactory.chair.WoodChair;
import com.gpcoder.patterns.creational.abstractfactory.factory.FurnitureAbstractFactory;
import com.gpcoder.patterns.creational.abstractfactory.table.Table;
import com.gpcoder.patterns.creational.abstractfactory.table.WoodTable;

public class WoodFactory extends FurnitureAbstractFactory {

	@Override
	public Chair createChair() {
		return new WoodChair();
	}

	@Override
	public Table createTable() {
		return new WoodTable();
	}
}

AbstractProduct và Product:

Chair:


package com.gpcoder.patterns.creational.abstractfactory.chair;

public interface Chair {
	void create();
}


package com.gpcoder.patterns.creational.abstractfactory.chair;

public class PlasticChair implements Chair {
	@Override
	public void create() {
		System.out.println("Create plastic chair");
	}
}


package com.gpcoder.patterns.creational.abstractfactory.chair;

public class WoodChair implements Chair {
	@Override
	public void create() {
		System.out.println("Create wood chair");
	}
}

Table:


package com.gpcoder.patterns.creational.abstractfactory.table;

public interface Table {
	void create();
}


package com.gpcoder.patterns.creational.abstractfactory.table;

public class PlasticTable implements Table {
	@Override
	public void create() {
		System.out.println("Create plastic table");
	}
}


package com.gpcoder.patterns.creational.abstractfactory.table;

public class WoodTable implements Table {
	@Override
	public void create() {
		System.out.println("Create wood table");
	}
}

Material type:


public enum MaterialType {
	FLASTIC, WOOD
}

Client:


package com.gpcoder.patterns.creational.abstractfactory;

import com.gpcoder.patterns.creational.abstractfactory.chair.Chair;
import com.gpcoder.patterns.creational.abstractfactory.factory.FurnitureAbstractFactory;
import com.gpcoder.patterns.creational.abstractfactory.factory.FurnitureFactory;
import com.gpcoder.patterns.creational.abstractfactory.table.Table;

public class Client {

	public static void main(String[] args) {

		FurnitureAbstractFactory factory = FurnitureFactory.getFactory(MaterialType.FLASTIC);

		Chair chair = factory.createChair();
		chair.create(); // Create plastic chair

		Table table = factory.createTable();
		table.create(); // Create plastic table
	}
}

Như bạn thấy, phía Client chỉ cần gọi phương thức FurnitureFactory.getFactory() là có thể sử dụng được các dịch vụ của một Factory bất kỳ.

Khi hệ thống phát triển cần mở rộng thêm 1 nhà máy khác, chẳng hạn sản xuất hàng hóa bằng inox, thì đơn giản cần tạo thêm một class mới implement từ FurnitureAbstractFactory, và thêm vào logic khởi tạo Funiture trong FurnitureFactory. Nó không làm ảnh hưởng đến code ở phía Client.

Lợi ích của Abstract Factory Pattern là gì?

  • Các lợi ích của Factory Pattern cũng tương tự như Factory Method Pattern như: cung cấp hướng tiếp cận với Interface thay thì các implement, che giấu sự phức tạp của việc khởi tạo các đối tượng với người dùng (client), độc lập giữa việc khởi tạo đối tượng và hệ thống sử dụng, …
  • Giúp tránh được việc sử dụng điều kiện logic bên trong Factory Pattern. Khi một Factory Method lớn (có quá nhiều sử lý if-else hay switch-case), chúng ta nên sử dụng theo mô hình Abstract Factory để dễ quản lý hơn (cách phân chia có thể là gom nhóm các sub-class cùng loại vào một Factory).
  • Abstract Factory Pattern là factory của các factory, có thể dễ dạng mở rộng để chứa thêm các factory và các sub-class khác.
  • Dễ dàng xây dựng một hệ thống đóng gói (encapsulate): sử dụng được với nhiều nhóm đối tượng (factory) và tạo nhiều product khác nhau.

Tài liệu tham khảo:

  • https://sourcemaking.com/design_patterns/abstract_factory
  • https://refactoring.guru/design-patterns/abstract-factory
  • https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java
4.8
42
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Creational Pattern, Design pattern Được gắn thẻ: Creational Design Pattern, Design pattern

Hướng dẫn Java Design Pattern – Factory Method
Hướng dẫn Java Design Pattern – Prototype

Có thể bạn muốn xem:

  • Hướng dẫn Java Design Pattern – Observer (28/12/2018)
  • Hướng dẫn Java Design Pattern – Service Locator (21/01/2019)
  • Giới thiệu Aspect Oriented Programming (AOP) (09/02/2019)
  • Hướng dẫn Java Design Pattern – Adapter (15/10/2018)
  • Giới thiệu Google Guice – Aspect Oriented Programming (AOP) (14/02/2019)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (97662 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97348 lượt xem)
  • Giới thiệu Design Patterns (87188 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (85899 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83409 lượt xem)

Nội dung bài viết

  • 1 Abstract Factory Pattern là gì?
  • 2 Cài đặt Abstract Factory Pattern như thế nào?
  • 3 Lợi ích của Abstract Factory Pattern là gì?

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link