Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Computer Science Design Patterns/Facade

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

reading 25 29 Jan, 2014 Add more illustrations. Decorator Factory method 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 { 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 processor; private Memory ram; private HardDrive hd; public Computer() { this.processor = new CPU(); this.ram = new Memory(); this.hd = new HardDrive(); } public void start() { processor.freeze(); ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE)); processor.jump(BOOT_ADDRESS); processor.execute(); } } /* Client */ class You { public static void main(String[] args) { Computer facade = new Computer(); facade.start(); } } Implementation in C# using System; namespace Facade { public class CPU { public void Freeze() { } public void Jump(long addr) { } public void Execute() { } } public class Memory { public void Load(long position, byte[] data) { } } public class HardDrive { public byte[] Read(long lba, int size) { return null; } } public class Computer { var cpu = new CPU(); var memory = new Memory(); var hardDrive = new HardDrive(); public void StartComputer() { cpu.Freeze(); memory.Load(0x22, hardDrive.Read(0x66, 0x99)); cpu.Jump(0x44); cpu.Execute(); } } public class SomeClass { public static void Main(string[] args) { var facade = new Computer(); facade.StartComputer(); } } } Implementation in Ruby # Complex parts class CPU def freeze; puts 'CPU: freeze'; end def jump(position); puts "CPU: jump to #{position}"; end def execute; puts 'CPU: execute'; end end class Memory def load(position, data) puts "Memory: load #{data} at #{position}" end end class HardDrive def read(lba, size) puts "HardDrive: read sector #{lba} (#{size} bytes)" return 'hdd data' end end # Facade class Computer BOOT_ADDRESS = 0 BOOT_SECTOR = 0 SECTOR_SIZE = 512 def initialize @cpu = CPU.new @memory = Memory.new @hard_drive = HardDrive.new end def start_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 class CPU: def freeze(self): pass def jump(self, position): pass def execute(self): pass class Memory: def load(self, position, data): pass class HardDrive: def read(self, lba, size): pass # Facade class Computer: def __init__(self): self.cpu = CPU() self.memory = Memory() self.hard_drive = HardDrive() def start_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 */ var CPU = function () {}; CPU.prototype = { freeze: function () { console.log('CPU: freeze'); }, jump: function (position) { console.log('CPU: jump to ' + position); }, execute: function () { console.log('CPU: execute'); } }; var Memory = function () {}; Memory.prototype = { load: function (position, data) { console.log('Memory: load "' + data + '" at ' + position); } }; var HardDrive = function () {}; HardDrive.prototype = { read: function (lba, size) { console.log('HardDrive: read sector ' + lba + '(' + size + ' bytes)'); return 'hdd data'; } }; /* Facade */ var Computer = function () { var cpu, memory, hardDrive; cpu = new CPU(); memory = new Memory(); hardDrive = new HardDrive(); var constant = function (name) { var constants = { BOOT_ADDRESS: 0, BOOT_SECTOR: 0, SECTOR_SIZE: 512 }; return constants[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 */ var facade = new Computer(); facade.startComputer(); Implementation in ActionScript 3.0 /* Complex Parts */ /* CPU.as */ package { public class CPU { public function freeze():void { trace("CPU::freeze"); } public function jump(addr:Number):void { trace("CPU::jump to", String(addr)); } public function execute():void { trace("CPU::execute"); } } } /* Memory.as */ package { import flash.utils.ByteArray; public class Memory { public function load(position:Number, data:ByteArray):void { trace("Memory::load position:", position, "data:", data); } } } /* HardDrive.as */ package { import flash.utils.ByteArray; public class HardDrive { public function read(lba:Number, size:int):ByteArray { trace("HardDrive::read returning null"); return null; } } } /* The Facade */ /* Computer.as */ package { public class Computer { public static const BOOT_ADDRESS:Number = 0x22; public static const BOOT_SECTOR:Number = 0x66; public static const SECTOR_SIZE:int = 0x200; private var _cpu:CPU; private var _memory:Memory; private var _hardDrive:HardDrive; public function Computer() { _cpu = new CPU(); _memory = new Memory(); _hardDrive = new HardDrive(); } public function startComputer():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 { import flash.display.MovieClip; public class Client extends MovieClip { private var _computer:Computer; public function Client() { _computer = new Computer(); _computer.startComputer(); } } } Implementation in Scala /* Complex parts */ package intel { class CPU { def freeze() = ??? def jump(position: Long) = ??? def execute() = ??? } } package ram.plain { class Memory { def load(position: Long, data: Array[Byte]) = ??? } } package hdd { class HardDrive { def read(lba: Long, size: Int): Array[Byte] = ??? } } /* Facade */ //imports for the facade import common.patterns.intel.CPU import common.patterns.ram.plain.Memory import common.patterns.hdd.HardDrive package pk { class ComputerFacade(conf: String) { val processor: CPU = new CPU val ram: Memory = new Memory val hd: HardDrive = new HardDrive val BOOT_ADDRESS: Long = ??? val BOOT_SECTOR: Long = ??? val SECTOR_SIZE: Int = ??? def start() = { processor.freeze() ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE)) processor.jump(BOOT_ADDRESS) processor.execute() } } } //imports for your package import common.patterns.pk.ComputerFacade /* Client */ object You { def main(args: Array[String]) { new ComputerFacade("conf").start() } } Implementation in Delphi program Facade; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type (* complex parts - > Subsystem *) TCPU = class procedure Freeze; procedure Jump(position: Integer); procedure Execute; end; TMemory = class procedure Load(position: Integer; data: string); end; THardDrive = class function Read(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 procedure Start_Computer; constructor Create; end; { TCPU } procedure TCPU.Execute; begin WriteLn('CPU: execute'); end; procedure TCPU.Freeze; begin WriteLn('CPU: freese'); end; procedure TCPU.Jump(position: Integer); begin WriteLn('CPU: jump to ' + IntToStr(position)); end; { TMemory } procedure TMemory.Load(position: Integer; data: string); begin WriteLn('Memory: load "' + data + '" at ' + IntToStr(position)); end; { THardDrive } function THardDrive.Read(lba, size: Integer): string; begin WriteLn('HardDrive: read sector ' + IntToStr(lba) + ' (' + IntToStr(size) + ' bytes)'); Result := 'hdd data'; end; { TComputer } constructor TComputer.Create; begin fCPU := TCPU.Create; fMemory := TMemory.Create; fHardDrive := THardDrive.Create; end; procedure TComputer.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 on E: Exception do WriteLn(E.ClassName, ': ', E.Message); end; end.