Facade

El patró facade (o patró de façana) és un patró de disseny generalment utilitzat en la programació orientada a objectes. El nom és una analogia a una façana arquitectònica.

Un facade és un objecte que proporciona una interfície simplificada a un cos més gran de codi, com una classe biblioteca. Un facade permet:

  • Facilitar l'ús, la comprensió i les proves, d'una biblioteca de programari, donat que el facade disposa de mètodes per a tasques comunes.
  • Facilitar la lectura de la biblioteca per la mateixa raó.
  • Reduir les dependències amb el codi exterior en el funcionament intern d'una biblioteca, ja que la majoria del codi utilitza la façana i permet una major flexibilitat en el desenvolupament del sistema.
  • Encapsular una col·lecció mal dissenyada d'APIs amb un sola API ben dissenyada (segons necessiti la tasca).

El patró de disseny Facade s'utilitza sovint quan un sistema és molt complex o difícil d'entendre perquè el sistema té un gran nombre de classes interdependents o el seu codi de font no està disponible. Aquest patró amaga la complexitat del sistema més gran i proporciona un interfície més senzilla per al client. Generalment es tracta d'una sola classe contenidor que engloba un conjunt de membres demanats pel client. Aquests membres accedeixen al sistema en nom del client façana i oculten els detalls d'implementació

S'utilitza el Facade quan es desitja una interfície més fàcil o més senzilla per un objecte subjacent.[1] Alternativament, es pot utilitzar un adaptador quan el contenidor ha de respectar una interfície particular i ha de donar suport a un comportament polimòrfic. Un decorador permet afegir o alterar el comportament d'una interfície en temps d'execuició.

Patró Propòsit
Adaptador Converteix un interfície a un altre de manera que aparella el que el client està esperant
Decorador Dinàmicament afegeix una responsabilitat a la interfície encapsulant el codi original
Facade Proporciona una interfície simplificada

El patro facade s'utilitza típicament quan:

  • Una interfície senzilla necessita accedir a un sistema complex.
  • Les abstraccions i les implementacions d'un subsistema estan estretament lligades.
  • Es necessita un punt d'entrada a cada capa del programari.
  • Un sistema és molt complex o difícil d'entendre.

Estructura

[modifica]

Facade
La classe "façade" abstreu els Packages 1, 2, i 3 de la resta de l'aplicació.
Clients
Els objectes estan utilitzant el patró Facade per accedir als recursos dels Paquets.

Exemple

[modifica]

Aquest és un exemple com un client interacciona amb un facade d'un sistema complex (parts internes d'un ordinador, com la CPU i el DiscDur).

Implementació

[modifica]
namespace IVSR.Designpattern.Facade
{
 class SubsystemA
 {
 public string OperationA1()
 {
 return "Subsystem A, Method A1\n";
 }
 public string OperationA2()
 {
 return "Subsystem A, Method A2\n";
 }
 }

 class SubsystemB
 {
 public string OperationB1()
 {
 return "Subsystem B, Method B1\n";
 }

 public string OperationB2()
 {
 return "Subsystem B, Method B2\n";
 }
 }

 class SubsystemC
 {
 public string OperationC1()
 {
 return "Subsystem C, Method C1\n";
 }

 public string OperationC2()
 {
 return "Subsystem C, Method C2\n";
 }
 }

 public class Facade
 {
 private SubsystemA a = new SubsystemA();
 private SubsystemB b = new SubsystemB();
 private SubsystemC c = new SubsystemC();
 public void Operation1()
 {
 Console.WriteLine("Operation 1\n" +
 a.OperationA1() +
 a.OperationA2() +
 b.OperationB1());
 }
 public void Operation2()
 {
 Console.WriteLine("Operation 2\n" +
 b.OperationB2() +
 c.OperationC1() +
 c.OperationC2());
 }
 }
}

Codi d'exemple

[modifica]
namespace IVSR.DesignPattern.Facade.Sample
{
 // The 'Subsystem ClassA' class
 class CarModel
 {
 public void SetModel()
 {
 Console.WriteLine(" CarModel - SetModel");
 }
 }

 /// <summary>
 /// The 'Subsystem ClassB' class
 /// </summary>
 class CarEngine
 {
 public void SetEngine()
 {
 Console.WriteLine(" CarEngine - SetEngine");
 }
 }

 // The 'Subsystem ClassC' class
 class CarBody
 {
 public void SetBody()
 {
 Console.WriteLine(" CarBody - SetBody");
 }
 }

 // The 'Subsystem ClassD' class
 class CarAccessories
 {
 public void SetAccessories()
 {
 Console.WriteLine(" CarAccessories - SetAccessories");
 }
 }

 // The 'Facade' class
 public class CarFacade
 {
 private CarModel model;
 private CarEngine engine;
 private CarBody body;
 private CarAccessories accessories;

 public CarFacade()
 {
 model = new CarModel();
 engine = new CarEngine();
 body = new CarBody();
 accessories = new CarAccessories();
 }

 public void CreateCompleteCar()
 {
 Console.WriteLine("******** Creant un cotxe **********\n");
 model.SetModel();
 engine.SetEngine();
 body.SetBody();
 accessories.SetAccessories();

 Console.WriteLine("\n******** Creació de cotxe complet **********");
 }
 }

 // Facade Pattern Demo
 class Program
 {
 static void Main(string[] args)
 {
 CarFacade facade = new CarFacade();

 facade.CreateCompleteCar();

 Console.ReadKey();

 }
 }
}

Referències

[modifica]
  1. Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates. Head First Design Patterns (paperback). 1. O'Reilly, 2004, p. 243, 252, 258, 260. ISBN 978-0-596-00712-6 [Consulta: 2 juliol 2012].