跳转到内容

外观

25% developed
来自维基教科书,开放的书籍,开放的世界

装饰器 计算机科学设计模式
外观
工厂方法

外观模式隐藏了系统的复杂性,并为客户端提供了一个接口,客户端可以通过该接口访问系统。将系统划分为子系统有助于降低复杂性。我们需要最小化子系统之间的通信和依赖关系。为此,我们引入了外观对象,它为子系统更通用的功能提供一个单一的、简化的接口。

示例

SCP命令是SSH命令的快捷方式。可以使用SSH连接编写多个命令来完成远程文件复制,但可以使用SCP命令在一个命令中完成。因此,SCP命令是SSH命令的外观。虽然它可能没有用面向对象编程的方式编码,但它很好地说明了设计模式。

成本

这种模式非常容易,没有额外的成本。

创建

这种模式非常容易创建。

维护

这种模式非常容易维护。

移除

这种模式也很容易移除。

建议

  • 不要使用这种模式来掩盖只有三到四个方法调用。

实现

Java实现

这是一个关于客户端(“你”)如何与外观(“电脑”)交互以访问复杂系统(内部电脑部件,如CPU和硬盘)的抽象示例。

/* 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();
    }
}
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();
            }
        }
}
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
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()
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();
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();
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();
        }
    }
}
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()
  }
}
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.


Clipboard

待办事项
添加更多示例。


装饰器 计算机科学设计模式
外观
工厂方法


您对本页有任何疑问吗?
在这里提问


在本图书中创建新页面


华夏公益教科书