VOOZH about

URL: https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Facade

⇱ Facade - Wikibooks, open books for an open world


Jump to content
From Wikibooks, open books for an open world
👁 Image
Decorator
Computer Science Design Patterns
Facade
Factory method 👁 Image

A Facade pattern hides the complexities of the system and provides an interface to the client from where the client can access the system. Dividing a system into subsystems helps reduce complexity. We need to minimize the communication and dependencies between subsystems. For this, we introduce a facade object that provides a single, simplified interface to the more general facilities of a subsystem.

Examples

The SCP command is a shortcut for SSH commands. A remote file copy could be done writing several commands with an SSH connection but it can be done in one command with SCP. So the SCP command is a facade for the SSH commands. Although it may not be coded in the object programming paradigm, it is a good illustration of the design pattern.

Cost

This pattern is very easy and has not additional cost.

Creation

This pattern is very easy to create.

Maintenance

This pattern is very easy to maintain.

Removal

This pattern is very easy to remove too.

Advises

  • Do not use this pattern to mask only three or four method calls.

Implementations

Implementation in Java

This is an abstract example of how a client ("you") interacts with a facade (the "computer") to a complex system (internal computer parts, like CPU and HardDrive).

/* Complex parts */

class CPU{
publicvoidfreeze(){...}
publicvoidjump(longposition){...}
publicvoidexecute(){...}
}
class Memory{
publicvoidload(longposition,byte[]data){...}
}
class HardDrive{
publicbyte[]read(longlba,intsize){...}
}
/* Facade */

class Computer{
privateCPUprocessor;
privateMemoryram;
privateHardDrivehd;

publicComputer(){
this.processor=newCPU();
this.ram=newMemory();
this.hd=newHardDrive();
}

publicvoidstart(){
processor.freeze();
ram.load(BOOT_ADDRESS,hd.read(BOOT_SECTOR,SECTOR_SIZE));
processor.jump(BOOT_ADDRESS);
processor.execute();
}
}
/* Client */

class You{
publicstaticvoidmain(String[]args){
Computerfacade=newComputer();
facade.start();
}
}
Implementation in C#
usingSystem;

namespaceFacade
{
publicclassCPU
{
publicvoidFreeze(){}
publicvoidJump(longaddr){}
publicvoidExecute(){}
}

publicclassMemory
{
publicvoidLoad(longposition,byte[]data){}
}

publicclassHardDrive
{
publicbyte[]Read(longlba,intsize){returnnull;}
}

publicclassComputer
{
varcpu=newCPU();
varmemory=newMemory();
varhardDrive=newHardDrive();

publicvoidStartComputer()
{
cpu.Freeze();
memory.Load(0x22,hardDrive.Read(0x66,0x99));
cpu.Jump(0x44);
cpu.Execute();
}
}

publicclassSomeClass
{
publicstaticvoidMain(string[]args)
{
varfacade=newComputer();
facade.StartComputer();
}
}
}
Implementation in Ruby
# Complex parts
classCPU
deffreeze;puts'CPU: freeze';end
defjump(position);puts"CPU: jump to #{position}";end
defexecute;puts'CPU: execute';end
end

classMemory
defload(position,data)
puts"Memory: load #{data} at #{position}"
end
end

classHardDrive
defread(lba,size)
puts"HardDrive: read sector #{lba} (#{size} bytes)"
return'hdd data'
end
end

# Facade
classComputer
BOOT_ADDRESS=0
BOOT_SECTOR=0
SECTOR_SIZE=512

definitialize
@cpu=CPU.new
@memory=Memory.new
@hard_drive=HardDrive.new
end

defstart_computer
@cpu.freeze
@memory.load(BOOT_ADDRESS,@hard_drive.read(BOOT_SECTOR,SECTOR_SIZE))
@cpu.jump(BOOT_ADDRESS)
@cpu.execute
end
end

# Client
facade=Computer.new
facade.start_computer
Implementation in Python
# Complex parts
classCPU:
 deffreeze(self): pass
 defjump(self, position): pass
 defexecute(self): pass
 
classMemory:
 defload(self, position, data): pass
 
classHardDrive:
 defread(self, lba, size): pass
 
# Facade
classComputer:
 def__init__(self):
 self.cpu = CPU()
 self.memory = Memory()
 self.hard_drive = HardDrive()
 
 defstart_computer(self):
 self.cpu.freeze()
 self.memory.load(0, self.hard_drive.read(0, 1024))
 self.cpu.jump(10)
 self.cpu.execute()
 
# Client
if __name__ == '__main__':
 facade = Computer()
 facade.start_computer()
Implementation in PHP
/* Complex parts */
class CPU
{
 public function freeze() { /* ... */ }
 public function jump( $position ) { /* ... */ }
 public function execute() { /* ... */ }

}

class Memory
{
 public function load( $position, $data ) { /* ... */ }
}

class HardDrive
{
 public function read( $lba, $size ) { /* ... */ }
}

/* Facade */
class Computer
{
 protected $cpu = null;
 protected $memory = null;
 protected $hardDrive = null;

 public function __construct()
 {
 $this->cpu = new CPU();
 $this->memory = new Memory();
 $this->hardDrive = new HardDrive();
 }

 public function startComputer()
 {
 $this->cpu->freeze();
 $this->memory->load( BOOT_ADDRESS, $this->hardDrive->read( BOOT_SECTOR, SECTOR_SIZE ) );
 $this->cpu->jump( BOOT_ADDRESS );
 $this->cpu->execute();
 }
}

/* Client */
$facade = new Computer();
$facade->startComputer();
Implementation in JavaScript
/* Complex parts */
varCPU=function(){};
CPU.prototype={
freeze:function(){
console.log('CPU: freeze');
},
jump:function(position){
console.log('CPU: jump to '+position);
},
execute:function(){
console.log('CPU: execute');
}
};

varMemory=function(){};
Memory.prototype={
load:function(position,data){
console.log('Memory: load "'+data+'" at '+position);
}
};

varHardDrive=function(){};
HardDrive.prototype={
read:function(lba,size){
console.log('HardDrive: read sector '+lba+'('+size+' bytes)');
return'hdd data';
}
};

/* Facade */
varComputer=function(){
varcpu,memory,hardDrive;

cpu=newCPU();
memory=newMemory();
hardDrive=newHardDrive();

varconstant=function(name){
varconstants={
BOOT_ADDRESS:0,
BOOT_SECTOR:0,
SECTOR_SIZE:512
};

returnconstants[name];
};

this.startComputer=function(){
cpu.freeze();
memory.load(constant('BOOT_ADDRESS'),hardDrive.read(constant('BOOT_SECTOR'),constant('SECTOR_SIZE')));
cpu.jump(constant('BOOT_ADDRESS'));
cpu.execute();
}

};

/* Client */
varfacade=newComputer();
facade.startComputer();
Implementation in ActionScript 3.0
/* Complex Parts */

/* CPU.as */
package
{
publicclassCPU
{
publicfunctionfreeze():void
{
trace("CPU::freeze");
}

publicfunctionjump(addr:Number):void
{
trace("CPU::jump to",String(addr));
}

publicfunctionexecute():void
{
trace("CPU::execute");
}
}
}

/* Memory.as */
package
{
importflash.utils.ByteArray;

publicclassMemory
{
publicfunctionload(position:Number,data:ByteArray):void
{
trace("Memory::load position:",position,"data:",data);
}
}
}

/* HardDrive.as */
package
{
importflash.utils.ByteArray;

publicclassHardDrive
{
publicfunctionread(lba:Number,size:int):ByteArray
{
trace("HardDrive::read returning null");
returnnull;
}
}
}

/* The Facade */
/* Computer.as */
package
{
publicclassComputer
{
publicstaticconstBOOT_ADDRESS:Number=0x22;
publicstaticconstBOOT_SECTOR:Number=0x66;
publicstaticconstSECTOR_SIZE:int=0x200;

privatevar_cpu:CPU;
privatevar_memory:Memory;
privatevar_hardDrive:HardDrive;

publicfunctionComputer()
{
_cpu=newCPU();
_memory=newMemory();
_hardDrive=newHardDrive();
}

publicfunctionstartComputer():void
{
_cpu.freeze();
_memory.load(BOOT_ADDRESS,_hardDrive.read(BOOT_SECTOR,SECTOR_SIZE));
_cpu.jump(BOOT_ADDRESS);
_cpu.execute();
}
}
}

/* Client.as : This is the application's Document class */
package
{
importflash.display.MovieClip;

publicclassClientextendsMovieClip
{
privatevar_computer:Computer;

publicfunctionClient()
{
_computer=newComputer();
_computer.startComputer();
}
}
}
Implementation in Scala
/* Complex parts */

packageintel{
classCPU{
deffreeze()=???
defjump(position:Long)=???
defexecute()=???
}
}

packageram.plain{
classMemory{
defload(position:Long,data:Array[Byte])=???
}
}

packagehdd{
classHardDrive{
defread(lba:Long,size:Int):Array[Byte]=???
}
}
/* Facade */
//imports for the facade
importcommon.patterns.intel.CPU
importcommon.patterns.ram.plain.Memory
importcommon.patterns.hdd.HardDrive

packagepk{
classComputerFacade(conf:String){
valprocessor:CPU=newCPU
valram:Memory=newMemory
valhd:HardDrive=newHardDrive

valBOOT_ADDRESS:Long=???
valBOOT_SECTOR:Long=???
valSECTOR_SIZE:Int=???

defstart()={
processor.freeze()
ram.load(BOOT_ADDRESS,hd.read(BOOT_SECTOR,SECTOR_SIZE))
processor.jump(BOOT_ADDRESS)
processor.execute()
}
}
}
//imports for your package
importcommon.patterns.pk.ComputerFacade

/* Client */

objectYou{
defmain(args:Array[String]){
newComputerFacade("conf").start()
}
}
Implementation in Delphi
programFacade;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils;

type
(* complex parts - > Subsystem *)
TCPU=class
procedureFreeze;
procedureJump(position:Integer);
procedureExecute;
end;

TMemory=class
procedureLoad(position:Integer;data:string);
end;

THardDrive=class
functionRead(lba,size:Integer):string;
end;

(* Facade *)
TComputer=class
fCPU:TCPU;
fMemory:TMemory;
fHardDrive:THardDrive;

const
BOOT_ADDRESS:Integer=0;
BOOT_SECTOR:Integer=0;
SECTOR_SIZE:Integer=512;
public
procedureStart_Computer;
constructorCreate;
end;

{ TCPU }

procedureTCPU.Execute;
begin
WriteLn('CPU: execute');
end;

procedureTCPU.Freeze;
begin
WriteLn('CPU: freese');
end;

procedureTCPU.Jump(position:Integer);
begin
WriteLn('CPU: jump to '+IntToStr(position));
end;

{ TMemory }

procedureTMemory.Load(position:Integer;data:string);
begin
WriteLn('Memory: load "'+data+'" at '+IntToStr(position));
end;

{ THardDrive }

functionTHardDrive.Read(lba,size:Integer):string;
begin
WriteLn('HardDrive: read sector '+IntToStr(lba)+' ('+IntToStr(size)+
' bytes)');
Result:='hdd data';
end;

{ TComputer }

constructorTComputer.Create;
begin
fCPU:=TCPU.Create;
fMemory:=TMemory.Create;
fHardDrive:=THardDrive.Create;
end;

procedureTComputer.Start_Computer;
begin
fCPU.Freeze;
fMemory.Load(BOOT_ADDRESS,fHardDrive.Read(BOOT_SECTOR,SECTOR_SIZE));
fCPU.Jump(BOOT_ADDRESS);
fCPU.Execute;
end;

var
facad:TComputer;

begin
try
{ TODO -oUser -cConsole Main : Insert code here }

facad:=TComputer.Create;
facad.Start_Computer;

WriteLn(#13#10+'Press any key to continue...');
ReadLn;

facad.Free;
except
onE:Exceptiondo
WriteLn(E.ClassName,': ',E.Message);
end;
end.


👁 Clipboard

To do:
Add more illustrations.


👁 Image
Decorator
Computer Science Design Patterns
Facade
Factory method 👁 Image



Ask it here: