8

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!

2 Answers 2

10

The relationship between the two: The Facade pattern is a subset of "layers of abstraction". A Facade is an added level of abstraction. Not all abstractions are Facades.

Specifically, a Facade is where we offer a simplified interface to a complex API. Sometimes we are wrapping numerous complex classes in one simple one; sometimes we are just taking one class with a complex API and simplifying it for the calling code.

If you are simply forwarding one call to another class with the same interface, that is more accurately the Proxy pattern. This is another type of abstraction layer.

Is it a good idea to abstract logging out in an MVC pattern? Yes (most MVC frameworks will do this for you). But whether you should be abstracting it using a Proxy or a Facade depends very much on the login API.

1
  • How do you differentiate when an abstraction is not a facade ?
    – Number945
    Commented Jul 11, 2020 at 15:39
2

You are totally interpreting it wrong. To sum up in one line "A facade pattern gives a simplified interface wherein we can use functionalities of a complex sub system". Use case of Facade pattern is to provide an accessor to the underlying low level methods of a complex service/package/component etc.

Following things don't come in the use case of facade :

  1. An abstraction for processes (This may be a part,but this should not be the sole purpose)
  2. Encapsulate processes in one process

Facade is used only for providing one concrete implementation for all the low level methods

A facade pattern should generally be used when we are designing a complex package which goes deep down into sub-systems and complexity. A Facade is just an accessor to the underlying lopw level metjods of a complex service/package/component etc.

Eg:

Step 1

Create an interface.

Shape.java:

public interface Shape {
   void draw();
}

Step 2

Create concrete classes implementing the same interface.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Rectangle::draw()");
   }
}

Square.java

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Square::draw()");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Circle::draw()");
   }
}

Step 3

Create a facade class.

ShapeMaker.java

public class ShapeMaker {
   private Shape circle;
   private Shape rectangle;
   private Shape square;

   public ShapeMaker() {
      circle = new Circle();
      rectangle = new Rectangle();
      square = new Square();
   }

   public void drawCircle(){
      circle.draw();
   }
   public void drawRectangle(){
      rectangle.draw();
   }
   public void drawSquare(){
      square.draw();
   }
}

Step 4

Use the facade to draw various types of shapes.

FacadePatternDemo.java

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();

      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();      
   }
}

Step 5

Verify the output.

Circle::draw()
Rectangle::draw()
Square::draw()

This pattern involves a single class which provides simplified methods required by client and delegates calls to methods of existing system classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.