The Facade pattern is a structural design pattern that provides a unified and simplified interface to a complex subsystem or a set of interfaces. It helps to make a subsystem easier to use by encapsulating its complexity and exposing only a simplified interface to the client.
<?php
// Subsystem Classes
class CPU {
public function start() {
echo "CPU is starting...\n";
}
public function execute() {
echo "CPU is executing instructions...\n";
}
public function stop() {
echo "CPU is stopping...\n";
}
}
class Memory {
public function load($position, $data) {
echo "Loading data into memory position $position\n";
}
}
class HardDrive {
public function read($lba, $size) {
echo "Reading $size bytes from sector $lba\n";
return "data";
}
}
// Facade Class
class ComputerFacade {
protected $cpu;
protected $memory;
protected $hardDrive;
public function __construct() {
$this->cpu = new CPU();
$this->memory = new Memory();
$this->hardDrive = new HardDrive();
}
public function startComputer() {
echo "Starting computer...\n";
$this->cpu->start();
$bootData = $this->hardDrive->read(0, 512);
$this->memory->load(0, $bootData);
$this->cpu->execute();
}
public function stopComputer() {
echo "Stopping computer...\n";
$this->cpu->stop();
}
}
// Client Code
$computer = new ComputerFacade();
$computer->startComputer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
$computer->stopComputer();
// Output:
// Stopping computer...
// CPU is stopping...
?>
// Subsystem Classes
class CPU {
start() {
console.log("CPU is starting...");
}
execute() {
console.log("CPU is executing instructions...");
}
stop() {
console.log("CPU is stopping...");
}
}
class Memory {
load(address, data) {
console.log(`Loading data into memory address ${address}`);
}
}
class HardDrive {
read(sector, size) {
console.log(`Reading ${size} bytes from sector ${sector}`);
return "data";
}
}
// Facade Class
class ComputerFacade {
constructor() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
startComputer() {
console.log("Starting computer...");
this.cpu.start();
const bootSector = 0;
const bootData = this.hardDrive.read(bootSector, 512);
this.memory.load(bootSector, bootData);
this.cpu.execute();
}
stopComputer() {
console.log("Stopping computer...");
this.cpu.stop();
}
}
// Client Code
const computer = new ComputerFacade();
computer.startComputer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory address 0
// CPU is executing instructions...
computer.stopComputer();
// Output:
// Stopping computer...
// CPU is stopping...
// Subsystem Classes
class CPU {
public void start() {
System.out.println("CPU is starting...");
}
public void execute() {
System.out.println("CPU is executing instructions...");
}
public void stop() {
System.out.println("CPU is stopping...");
}
}
class Memory {
public void load(long position, String data) {
System.out.println("Loading data into memory position " + position);
}
}
class HardDrive {
public String read(long lba, int size) {
System.out.println("Reading " + size + " bytes from sector " + lba);
return "data";
}
}
// Facade Class
class ComputerFacade {
private final CPU cpu;
private final Memory memory;
private final HardDrive hardDrive;
public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
public void startComputer() {
System.out.println("Starting computer...");
cpu.start();
String bootData = hardDrive.read(0, 512);
memory.load(0, bootData);
cpu.execute();
}
public void stopComputer() {
System.out.println("Stopping computer...");
cpu.stop();
}
}
// Client Code
public class FacadePatternExample {
public static void main(String[] args) {
ComputerFacade computer = new ComputerFacade();
computer.startComputer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
computer.stopComputer();
// Output:
// Stopping computer...
// CPU is stopping...
}
}
# Subsystem Classes
class CPU:
def start(self):
print("CPU is starting...")
def execute(self):
print("CPU is executing instructions...")
def stop(self):
print("CPU is stopping...")
class Memory:
def load(self, position, data):
print(f"Loading data into memory position {position}")
class HardDrive:
def read(self, lba, size):
print(f"Reading {size} bytes from sector {lba}")
return "data"
# Facade Class
class ComputerFacade:
def __init__(self):
self.cpu = CPU()
self.memory = Memory()
self.hard_drive = HardDrive()
def start_computer(self):
print("Starting computer...")
self.cpu.start()
boot_data = self.hard_drive.read(0, 512)
self.memory.load(0, boot_data)
self.cpu.execute()
def stop_computer(self):
print("Stopping computer...")
self.cpu.stop()
# Client Code
if __name__ == "__main__":
computer = ComputerFacade()
computer.start_computer()
# Output:
# Starting computer...
# CPU is starting...
# Reading 512 bytes from sector 0
# Loading data into memory position 0
# CPU is executing instructions...
computer.stop_computer()
# Output:
# Stopping computer...
# CPU is stopping...
using System;
// Subsystem Classes
class CPU
{
public void Start()
{
Console.WriteLine("CPU is starting...");
}
public void Execute()
{
Console.WriteLine("CPU is executing instructions...");
}
public void Stop()
{
Console.WriteLine("CPU is stopping...");
}
}
class Memory
{
public void Load(long position, string data)
{
Console.WriteLine($"Loading data into memory position {position}");
}
}
class HardDrive
{
public string Read(long lba, int size)
{
Console.WriteLine($"Reading {size} bytes from sector {lba}");
return "data";
}
}
// Facade Class
class ComputerFacade
{
private CPU _cpu;
private Memory _memory;
private HardDrive _hardDrive;
public ComputerFacade()
{
_cpu = new CPU();
_memory = new Memory();
_hardDrive = new HardDrive();
}
public void StartComputer()
{
Console.WriteLine("Starting computer...");
_cpu.Start();
string bootData = _hardDrive.Read(0, 512);
_memory.Load(0, bootData);
_cpu.Execute();
}
public void StopComputer()
{
Console.WriteLine("Stopping computer...");
_cpu.Stop();
}
}
// Client Code
class Program
{
static void Main(string[] args)
{
ComputerFacade computer = new ComputerFacade();
computer.StartComputer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
computer.StopComputer();
// Output:
// Stopping computer...
// CPU is stopping...
}
}
#include <iostream>
#include <string>
// Subsystem Classes
class CPU {
public:
void start() {
std::cout << "CPU is starting..." << std::endl;
}
void execute() {
std::cout << "CPU is executing instructions..." << std::endl;
}
void stop() {
std::cout << "CPU is stopping..." << std::endl;
}
};
class Memory {
public:
void load(long position, const std::string& data) {
std::cout << "Loading data into memory position " << position << std::endl;
}
};
class HardDrive {
public:
std::string read(long lba, int size) {
std::cout << "Reading " << size << " bytes from sector " << lba << std::endl;
return "data";
}
};
// Facade Class
class ComputerFacade {
private:
CPU cpu;
Memory memory;
HardDrive hardDrive;
public:
void startComputer() {
std::cout << "Starting computer..." << std::endl;
cpu.start();
std::string bootData = hardDrive.read(0, 512);
memory.load(0, bootData);
cpu.execute();
}
void stopComputer() {
std::cout << "Stopping computer..." << std::endl;
cpu.stop();
}
};
// Client Code
int main() {
ComputerFacade computer;
computer.startComputer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
computer.stopComputer();
// Output:
// Stopping computer...
// CPU is stopping...
return 0;
}
// Subsystem Classes
class CPU {
void start() {
print('CPU is starting...');
}
void execute() {
print('CPU is executing instructions...');
}
void stop() {
print('CPU is stopping...');
}
}
class Memory {
void load(int position, String data) {
print('Loading data into memory position $position');
}
}
class HardDrive {
String read(int lba, int size) {
print('Reading $size bytes from sector $lba');
return 'data';
}
}
// Facade Class
class ComputerFacade {
final CPU cpu;
final Memory memory;
final HardDrive hardDrive;
ComputerFacade()
: cpu = CPU(),
memory = Memory(),
hardDrive = HardDrive();
void startComputer() {
print('Starting computer...');
cpu.start();
String bootData = hardDrive.read(0, 512);
memory.load(0, bootData);
cpu.execute();
}
void stopComputer() {
print('Stopping computer...');
cpu.stop();
}
}
// Client Code
void main() {
ComputerFacade computer = ComputerFacade();
computer.startComputer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
computer.stopComputer();
// Output:
// Stopping computer...
// CPU is stopping...
}
// Subsystem Classes
struct CPU;
impl CPU {
fn start(&self) {
println!("CPU is starting...");
}
fn execute(&self) {
println!("CPU is executing instructions...");
}
fn stop(&self) {
println!("CPU is stopping...");
}
}
struct Memory;
impl Memory {
fn load(&self, position: u64, data: &str) {
println!("Loading data into memory position {}", position);
}
}
struct HardDrive;
impl HardDrive {
fn read(&self, lba: u64, size: u64) -> String {
println!("Reading {} bytes from sector {}", size, lba);
"data".to_string()
}
}
// Facade Class
struct ComputerFacade {
cpu: CPU,
memory: Memory,
hard_drive: HardDrive,
}
impl ComputerFacade {
fn new() -> Self {
ComputerFacade {
cpu: CPU,
memory: Memory,
hard_drive: HardDrive,
}
}
fn start_computer(&self) {
println!("Starting computer...");
self.cpu.start();
let boot_data = self.hard_drive.read(0, 512);
self.memory.load(0, &boot_data);
self.cpu.execute();
}
fn stop_computer(&self) {
println!("Stopping computer...");
self.cpu.stop();
}
}
// Client Code
fn main() {
let computer = ComputerFacade::new();
computer.start_computer();
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
computer.stop_computer();
// Output:
// Stopping computer...
// CPU is stopping...
}
package main
import "fmt"
// Subsystem Classes
type CPU struct{}
func (cpu *CPU) Start() {
fmt.Println("CPU is starting...")
}
func (cpu *CPU) Execute() {
fmt.Println("CPU is executing instructions...")
}
func (cpu *CPU) Stop() {
fmt.Println("CPU is stopping...")
}
type Memory struct{}
func (memory *Memory) Load(position int, data string) {
fmt.Printf("Loading data into memory position %d\n", position)
}
type HardDrive struct{}
func (hardDrive *HardDrive) Read(lba int, size int) string {
fmt.Printf("Reading %d bytes from sector %d\n", size, lba)
return "data"
}
// Facade Class
type ComputerFacade struct {
cpu *CPU
memory *Memory
hardDrive *HardDrive
}
func NewComputerFacade() *ComputerFacade {
return &ComputerFacade{
cpu: &CPU{},
memory: &Memory{},
hardDrive: &HardDrive{},
}
}
func (cf *ComputerFacade) StartComputer() {
fmt.Println("Starting computer...")
cf.cpu.Start()
bootData := cf.hardDrive.Read(0, 512)
cf.memory.Load(0, bootData)
cf.cpu.Execute()
}
func (cf *ComputerFacade) StopComputer() {
fmt.Println("Stopping computer...")
cf.cpu.Stop()
}
// Client Code
func main() {
computer := NewComputerFacade()
computer.StartComputer()
// Output:
// Starting computer...
// CPU is starting...
// Reading 512 bytes from sector 0
// Loading data into memory position 0
// CPU is executing instructions...
computer.StopComputer()
// Output:
// Stopping computer...
// CPU is stopping...
}
CPU, Memory, and HardDrive represent different components of a computer system, each with specific methods to perform operations.
Facade Class:
ComputerFacade provides a simplified interface (StartComputer() and StopComputer()) that encapsulates the interactions with the CPU, Memory, and HardDrive.
Client Code:
The client interacts with the computer system through the ComputerFacade class, which simplifies the process of starting and stopping the computer without needing to understand the complexities of each subsystem.
Complex Systems: When dealing with a complex system involving multiple classes and interactions.
API Wrapping: Simplifying the use of a library or API that has a complicated interface.
The Facade pattern is beneficial for providing a cleaner and more understandable interface to a complex system, making it easier for clients to interact with without needing to understand the underlying complexity.