UI Render System - Factory Pattern Implementation
This is an implementation of the Factory design pattern for a cross-platform UI framework that renders OS-specific components without the client code needing to know which operating system it's running on.
Problem Statement
Building a UI framework that runs on both Windows and Mac operating systems. The challenge is to render platform-specific UI components while keeping the client code completely decoupled from the underlying OS-specific implementations.
Key Challenge:
- Windows Button →
[WINDOWS] Rendering a Windows style button. - Mac Button →
[MAC] Rendering a Mac style button. - Client code must never use
new WindowsButton()ornew MacButton()directly - Adding new OS support should not require changes to client code
Class Diagram
+----------------------+
| UIFactory |
+----------------------+
| + createButton() |
+----------+-----------+
|
| (Creates)
v
+----------------------+
| Button |
| (Interface) |
+----------------------+
| + render() |
+----------+-----------+
^
| (Implements)
+----------------+----------------+
| |
+----------+----------+ +----------+----------+
| WindowsButton | | MacButton |
+---------------------+ +---------------------+
| + render() | | + render() |
+---------------------+ +---------------------+
Implementation
package factory.uirendersystem;
public class UIRenderSystem {
/**
* Enum to define supported operating systems.
* Ensures type safety and prevents invalid string inputs.
*/
enum OperatingSystem {
WINDOWS,
MAC
}
/**
* Component Interface.
* Defines the contract all platform-specific buttons must follow.
*/
interface Button {
void render();
}
/**
* Concrete Product for Windows.
* Renders a Windows-style button.
*/
static class WindowsButton implements Button {
@Override
public void render() {
System.out.println("[WINDOWS] Rendering a Windows style button.");
}
}
/**
* Concrete Product for Mac.
* Renders a Mac-style button.
*/
static class MacButton implements Button {
@Override
public void render() {
System.out.println("[MAC] Rendering a Mac style button.");
}
}
/**
* The Factory Class.
* This is the ONLY place where the new keyword is used to
* instantiate concrete button classes.
* The client remains completely ignorant of which class is created.
*/
static class UIFactory {
public Button createButton(OperatingSystem operatingSystem) {
return switch (operatingSystem) {
case WINDOWS -> new WindowsButton();
case MAC -> new MacButton();
default -> throw new IllegalArgumentException(
"Unsupported OS Type"
);
};
}
}
/**
* Main driver method.
* The client only interacts with the Factory and the Button Interface.
* It never references WindowsButton or MacButton directly.
*/
public static void main(String[] args) {
System.out.println("---- Cross-Platform UI Library ----");
UIFactory uiFactory = new UIFactory();
Button windowsBtn = uiFactory.createButton(OperatingSystem.WINDOWS);
windowsBtn.render();
Button macBtn = uiFactory.createButton(OperatingSystem.MAC);
macBtn.render();
}
}
Key Features
- Factory Pattern: Centralizes platform-specific object creation in one place
- Type Safety: Uses Enum for OS types instead of raw strings
-
Loose Coupling: Client only depends on the
Buttoninterface, never on concrete classes - Platform Independence: Client code works identically regardless of OS
- Open/Closed Principle: Add new OS support without modifying existing code
- Extensible: New platforms require only a new class and a new Enum value
How It Works
-
Interface (Button): Defines the
render()contract all platform buttons must follow - Concrete Classes: Each class implements its own OS-specific rendering logic
-
Factory (UIFactory): Takes an
OperatingSystemEnum and returns the right button object - Client (main): Only talks to the factory and the interface — never touches concrete classes directly
Top comments (0)