I just read about the facade pattern and found this example where a client (user of a computer) invokes a startComputer()
method which calls on all the complex stuff:
Source: wikipedia
/* Complex parts */
class CPU {
public void freeze() { ... }
public void jump(long position) { ... }
public void execute() { ... }
}
class Memory {
public void load(long position, byte[] data) { ... }
}
class HardDrive {
public byte[] read(long lba, int size) { ... }
}
/* Facade */
class Computer {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;
public Computer() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
public void startComputer() {
cpu.freeze();
memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE));
cpu.jump(BOOT_ADDRESS);
cpu.execute();
}
}
/* Client */
class You {
public static void main(String[] args) {
Computer facade = new Computer();
facade.startComputer();
}
}
Here we can see the client class (You) creating a new facade, calling the startComputer()
method. This method instantiates several objects and invokes their methods, encapsulating it inside the facade class where it 'glues it together'
.
Question 1:
But exactly how is this different from layers of abstraction?
Yesterday I made login functionality for a web application where a doLogin($username, $password)
encapsulated a 'complex'
lower-layer method call that updated login info about the user, set sessions to log in with and instantiated several objects etc. to do this job.
This layer would also call another even lower level which would deal with CRUD-like operations such as checking activation status, account existance and other things like processing strings through hashing algorithms. This method (on model level, look 'layer overview' below) would return an array with either a 'success'
key or a 'error_message'
key, acting as a boolean of sorts to the layer calling it.
This is what I understand is known as 'abstraction layers'
, hiding complex procedures from the higher-level architecture, but when I read about the facade pattern it seems like I have been using it all along?
Question 2:
Would my approach to abstracting the login mechanism be a bad choice in a MVC architecture? (if not, please give examples why)
Taken into consideration it should be very easy to decide where the end result goes (HTML, AJAX, etc.), wouldn't this be a wise choice to avoid alot of IFs as this can be dealt with on a controller layer?
Layer overview:
Controller layer: $model->doLogin(POST VARIABLES HERE)
Model layer: (Is this a facade?) Sets sessions, updates login information in database etc., calls independent components for information: $user_id = $user->getId();
and $session->sessionExists();
Independent class layer: Each class on this layer is independent and has little to no coupling. After all, why would it? It's the layer above's job to build the application and lend an API to control it with.
Question 3:
Is the facade pattern only used for routing calls to sub-classes in an API-like form, or perhaps just most commonly?
With this I mean: Object A instantiates object B and lends a method to control object B's methods through a method of it's own:
<?php
class A {
private $_objectB;
public function __construct()
{
$this->_objectB = new B();
}
public function callMethodB()
{
$this->_objectB->methodB();
}
}
class B {
public function methodB()
{
die('Wuhu!');
}
}
// --------------------------
$objectA->callMethodB(); // Wuhu!
instead of:
$objectA->objectB->methodB(); // Wuhu!