The facade pattern

The facade pattern is a simple pattern used to group the interfaces of a group of objects and a unified interface that is easier to use by a client.

Roles

The facade pattern allows you to provide the operations that might be desirable by a user. The pattern encapsulates the interface of each object that is considered as a low-level interface. To construct the unified interface, we might need to implement some methods that will compose the low-level interfaces:

  • It must be used to provide a simple interface of a complex system. The architecture of the system can be composed of several small classes that allow great modularity, but clients don't need such properties. They only need something simple that meets to their needs.
  • It can be used to divide the system into subsystems. The façade will be an interface that allows the communication between subsystems.
  • It can be also used to encapsulate the implementation of a system toward an external consumer.

Design

The facade pattern is designed to hide the complexity of a system. Its interface can be entirely new. It must not conform to the existing interface. We can provide several facades to the same system depending on the end user that we have and the functionality that we want to provide to the facade:

Design

Participants

The participants of this pattern are as follows:

  • Facade and its interface are the abstract parts of the system that are exposed to the clients. This class has some references to classes and components that are part of the system, and they have their methods used by the facade to implement the unified interface.
  • The classes and components of the system implement the functionalities of the system and answer requests coming from the facade. They do not need the facade to be able to work.

Collaboration

Clients communicate with the system through the facade façade. Then, the façade itself invokes classes and components of the system. The facade doesn't only send requests to classes and components of the subsystem. It must also adapt its own interface to the objects and components interfaces, using a specific code to allow communication of objects.

The following sequence diagram describes this case:

Collaboration

Clients using the facade should not directly access the objects of the system.

Illustration

We want to provide a simple interface to provide our clients with an easy way to find hotels near an input address and corresponding to some criteria (such as the number of stars.)

In our company, we have a subsystem that provides a catalog of hotels that includes their locations and number of stars for each of them.

We already have a FindPoi Webservice that can search for a hotel near a location point (latitude and longitude), which uses some criteria: the maximum distance to search and the numbers of stars we want.

As you can see, the service needs a location point, which means that we pass an object with a latitude and longitude.

As the consumer of our facade will only tell us its real address, we need services that will geocode the address to a GPS point with a latitude and longitude.

The sequence diagram shows you what we will do to provide our simplified interface:

Illustration

Open the Xcode project called FacadePattern and the main.swift file. This file represents a client that will consume our facade.

Our facade is, in fact, a service that allows a client to search for a hotel near the location that is sent as an input that has two criteria: distanceMax and number of stars for the hotel.

This is how the service will be called:

var results = svcFacadeFindHotel.findHotel(myAdress, distanceMax: 2.0, stars: 4)

The complete code of the client is as follows:

import Foundation


//I am a consumer of the service
// my addess is
// 1 infinite Loop
// Cupertino, CA 95014

let svcFacadeFindHotel = ServiceFindHotelNearBy()

let myAdress = " 1 Infinite Loop Cupertino, CA 95014 USA"
var results = svcFacadeFindHotel.findHotel(myAdress, distanceMax: 2.0, stars: 4)

print("*** RESULTS ")
print("Their is (results?.count) results :")

if let results = results {
  for var h in results{
    print("Hotel latitude:(h.location.latitude) longitude:(h.location.longitude), stars: (h.stars)")
  }
}

We open a connection for our ServiceFindHotelNearBy service. We tell what our current address is and then display the results if any. Here, we have 125 results (from 1,000 generated in the HotelCatalog object):

Illustration

Implementation of the facade

Based on the sequence diagram and method of the service consumed by the client, the facade called ServiceFindHotelNearBy in our sample project will have the following code:

import Foundation

class ServiceFindHotelNearBy: ServiceFindHotelNearByProtocol {
  
  //return a list of hotel that corresponds to our criteria
  func findHotel(from: String, distanceMax: Double, stars: Int) -> [Hotel]? {
      let svcGeocoding = Geocoding()
      let svcFindPoi = FindPoi()
      let systemhotelCatalog = HotelCatalog()
    
      //Geocode our adress to GPS Points
      let fromLocation = svcGeocoding.getGeocoordinates(from)
    
      //retrieve all hotels in the catalog
      let allHotels = systemhotelCatalog.getCatalog()
    
      //find POI that corresponds to our criteria
      let results = svcFindPoi.findPoiNearBy(fromLocation, distanceMax: distanceMax, stars: stars, catalog: allHotels)
    return results
  }
}

The facade is well-described as follows:

  • First, we make a connection to all the needed systems: the Geocoding, FindPoi, and SystemHotelCatalog Webservices (our subsystems).
  • Then, we orchestrate our calls based on the sequence diagram.
  • We first geocode the address into a GPS point.
  • Then, we get allHotels from the systemHotelCatalog object (which represent a subsystem) because we need to send it as an argument to the FindPoi service.
  • This is what we need to do in our next statement. We need to pass the distanceMax value, number of stars value, and GPS point we just geocoded as arguments of the findPoiNearBy method of the FindPoi service.
  • Then, we return the results to the client.

As you can see, the facade has encapsulated all the needed calls to the subsystem, hiding the complexity of retrieving hotels corresponding to the wishes of the client. This concludes the description of the facade pattern.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset