Cross-Platform UI
Create UI elements for different operating systems (Windows, Mac, Linux).
Ce contenu n’est pas encore disponible dans votre langue.
The Abstract Factory is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. It ensures that created objects are compatible with each other.
Abstract Factory is a super-factory that creates other factories. It provides a way to encapsulate a group of individual factories with a common theme without specifying their concrete classes, ensuring consistency among products.
Cross-Platform UI
Create UI elements for different operating systems (Windows, Mac, Linux).
Theme Systems
Generate consistent UI components for different themes (Dark, Light).
Database Adapters
Create database-specific connection, query, and result objects.
Document Formats
Generate complete document sets in different formats (PDF, Word, HTML).
| Advantages ✅ | Disadvantages ❌ |
|---|---|
| Ensures product compatibility. | Complex to implement and understand. |
| Isolates concrete classes. | Difficult to support new product types. |
| Promotes consistency among products. | Increases number of classes. |
| Follows Single Responsibility Principle. | Can be overkill for simple scenarios. |
The pattern consists of five main components:
// Abstract Productsinterface Button {render(): string;onClick(): void;}
interface Checkbox {render(): string;toggle(): void;}
// Concrete Products - Windowsclass WindowsButton implements Button {render(): string {return "Rendering Windows button";}onClick(): void {console.log("Windows button clicked");}}
class WindowsCheckbox implements Checkbox {render(): string {return "Rendering Windows checkbox";}toggle(): void {console.log("Windows checkbox toggled");}}
// Concrete Products - Macclass MacButton implements Button {render(): string {return "Rendering Mac button";}onClick(): void {console.log("Mac button clicked");}}
class MacCheckbox implements Checkbox {render(): string {return "Rendering Mac checkbox";}toggle(): void {console.log("Mac checkbox toggled");}}
// Abstract Factoryinterface GUIFactory {createButton(): Button;createCheckbox(): Checkbox;}
// Concrete Factoriesclass WindowsFactory implements GUIFactory {createButton(): Button {return new WindowsButton();}createCheckbox(): Checkbox {return new WindowsCheckbox();}}
class MacFactory implements GUIFactory {createButton(): Button {return new MacButton();}createCheckbox(): Checkbox {return new MacCheckbox();}}
// Client Codeclass Application {private button: Button;private checkbox: Checkbox;
constructor(factory: GUIFactory) {this.button = factory.createButton();this.checkbox = factory.createCheckbox();}
render(): void {console.log(this.button.render());console.log(this.checkbox.render());}}
// Usageconst os = "Windows"; // or "Mac"const factory: GUIFactory = os === "Windows"? new WindowsFactory(): new MacFactory();
const app = new Application(factory);app.render();// Abstract Productsinterface Button {String render();void onClick();}
interface Checkbox {String render();void toggle();}
// Concrete Products - Windowsclass WindowsButton implements Button {public String render() {return "Rendering Windows button";}public void onClick() {System.out.println("Windows button clicked");}}
class WindowsCheckbox implements Checkbox {public String render() {return "Rendering Windows checkbox";}public void toggle() {System.out.println("Windows checkbox toggled");}}
// Abstract Factoryinterface GUIFactory {Button createButton();Checkbox createCheckbox();}
// Concrete Factoryclass WindowsFactory implements GUIFactory {public Button createButton() {return new WindowsButton();}public Checkbox createCheckbox() {return new WindowsCheckbox();}}
// Clientclass Application {private Button button;private Checkbox checkbox;
public Application(GUIFactory factory) {button = factory.createButton();checkbox = factory.createCheckbox();}
public void render() {System.out.println(button.render());System.out.println(checkbox.render());}}// Abstract Productsinterface Button {public function render(): string;public function onClick(): void;}
interface Checkbox {public function render(): string;public function toggle(): void;}
// Concrete Productsclass WindowsButton implements Button {public function render(): string {return "Rendering Windows button";}public function onClick(): void {echo "Windows button clicked\n";}}
class WindowsCheckbox implements Checkbox {public function render(): string {return "Rendering Windows checkbox";}public function toggle(): void {echo "Windows checkbox toggled\n";}}
// Abstract Factoryinterface GUIFactory {public function createButton(): Button;public function createCheckbox(): Checkbox;}
// Concrete Factoryclass WindowsFactory implements GUIFactory {public function createButton(): Button {return new WindowsButton();}public function createCheckbox(): Checkbox {return new WindowsCheckbox();}}
// Usage$factory = new WindowsFactory();$button = $factory->createButton();echo $button->render();// Abstract Productstrait Button {fn render(&self) -> String;fn on_click(&self);}
trait Checkbox {fn render(&self) -> String;fn toggle(&self);}
// Concrete Productsstruct WindowsButton;impl Button for WindowsButton {fn render(&self) -> String {"Rendering Windows button".to_string()}fn on_click(&self) {println!("Windows button clicked");}}
struct WindowsCheckbox;impl Checkbox for WindowsCheckbox {fn render(&self) -> String {"Rendering Windows checkbox".to_string()}fn toggle(&self) {println!("Windows checkbox toggled");}}
// Abstract Factorytrait GUIFactory {fn create_button(&self) -> Box<dyn Button>;fn create_checkbox(&self) -> Box<dyn Checkbox>;}
// Concrete Factorystruct WindowsFactory;impl GUIFactory for WindowsFactory {fn create_button(&self) -> Box<dyn Button> {Box::new(WindowsButton)}fn create_checkbox(&self) -> Box<dyn Checkbox> {Box::new(WindowsCheckbox)}}
// Usagefn main() {let factory: &dyn GUIFactory = &WindowsFactory;let button = factory.create_button();println!("{}", button.render());}import { Component } from 'vue';
export interface ThemeFactory {createButton(): Component;createCard(): Component;createInput(): Component;}
// factories/LightThemeFactory.tsimport { ThemeFactory } from '../types/theme';import LightButton from '../components/light/LightButton.vue';import LightCard from '../components/light/LightCard.vue';import LightInput from '../components/light/LightInput.vue';
export class LightThemeFactory implements ThemeFactory {createButton() { return LightButton; }createCard() { return LightCard; }createInput() { return LightInput; }}
// factories/DarkThemeFactory.tsimport { ThemeFactory } from '../types/theme';import DarkButton from '../components/dark/DarkButton.vue';import DarkCard from '../components/dark/DarkCard.vue';import DarkInput from '../components/dark/DarkInput.vue';
export class DarkThemeFactory implements ThemeFactory {createButton() { return DarkButton; }createCard() { return DarkCard; }createInput() { return DarkInput; }}<script setup lang="ts">import { ref, computed } from 'vue';import { LightThemeFactory } from './factories/LightThemeFactory';import { DarkThemeFactory } from './factories/DarkThemeFactory';
const isDark = ref(false);
const factory = computed(() =>isDark.value ? new DarkThemeFactory() : new LightThemeFactory());
const ButtonComponent = computed(() => factory.value.createButton());const CardComponent = computed(() => factory.value.createCard());</script>
<template><div><button @click="isDark = !isDark">Toggle Theme</button><component :is="ButtonComponent">Click Me</component><component :is="CardComponent"> <p>Card content</p></component></div></template>// Abstract Productsinterface Connection {connect(): void;disconnect(): void;}
interface Query {execute(sql: string): void;}
interface Result {fetch(): any[];}
// MySQL Productsclass MySQLConnection implements Connection {connect(): void {console.log("Connecting to MySQL database");}disconnect(): void {console.log("Disconnecting from MySQL");}}
class MySQLQuery implements Query {execute(sql: string): void {console.log(`Executing MySQL query: ${sql}`);}}
class MySQLResult implements Result {fetch(): any[] {return [{ id: 1, name: "MySQL Data" }];}}
// PostgreSQL Productsclass PostgreSQLConnection implements Connection {connect(): void {console.log("Connecting to PostgreSQL database");}disconnect(): void {console.log("Disconnecting from PostgreSQL");}}
class PostgreSQLQuery implements Query {execute(sql: string): void {console.log(`Executing PostgreSQL query: ${sql}`);}}
class PostgreSQLResult implements Result {fetch(): any[] {return [{ id: 1, name: "PostgreSQL Data" }];}}
// Abstract Factoryinterface DatabaseFactory {createConnection(): Connection;createQuery(): Query;createResult(): Result;}
// Concrete Factoriesclass MySQLFactory implements DatabaseFactory {createConnection(): Connection {return new MySQLConnection();}createQuery(): Query {return new MySQLQuery();}createResult(): Result {return new MySQLResult();}}
class PostgreSQLFactory implements DatabaseFactory {createConnection(): Connection {return new PostgreSQLConnection();}createQuery(): Query {return new PostgreSQLQuery();}createResult(): Result {return new PostgreSQLResult();}}
// Clientclass DatabaseService {private connection: Connection;private query: Query;
constructor(factory: DatabaseFactory) {this.connection = factory.createConnection();this.query = factory.createQuery();}
executeQuery(sql: string): void {this.connection.connect();this.query.execute(sql);this.connection.disconnect();}}
// Usageconst dbType = process.env.DB_TYPE || "mysql";const factory = dbType === "mysql"? new MySQLFactory(): new PostgreSQLFactory();
const dbService = new DatabaseService(factory);dbService.executeQuery("SELECT * FROM users");Ensure Compatibility
All products from a factory must be compatible with each other.
Use Dependency Injection
Pass factories to clients through constructors or parameters.
Keep Families Cohesive
Products in a family should have a strong relationship.
Document Families
Clearly document which products belong to which family.
| Abstract Factory | Factory Method |
|---|---|
| Creates families of related objects | Creates one type of object |
| Uses composition | Uses inheritance |
| Factory is an object | Factory is a method |
| Multiple product types | Single product type |