facade这个词,原意指的是一个建筑物的表面、外观,在建筑学中被翻译为“立面”这个术语,国内对facade这个词的关注,可能更多要依赖于laravel的流行,似乎都一致把laravel里的facade翻译作“门面”。说实在的,当第一次看到翻译文档里提什么“门面”的时候,我想你跟我的内心一样:“这是在说什么玩意呢?你是在讲商店、店铺的门面吗?”直到现在,如果非得用中文说facade,非得用“门面”这个词,我的心里还是不自觉地会“咯噔”那么一下,我知道这里是有问题的。
facade到底翻译作啥好呢?倒是也有的人群干脆提倡不翻译,遇到它就直接英文单词拿过来,这也不是个长远办法,终归是要为了新入门的人铺平理解的道路才好。后来偶然看到台湾的学者,确切说是台湾的维基百科,将facade pattern译作“外观模式”,考虑到该模式的实际作用,方才感觉瞬间释然。即使laravel里的facade,严格上并不是facade pattern,很多人到现在依然在批评laravel在facade这个词语上的滥用和误导,但它终归也是在借用或模仿facade pattern,所以laravel里的facade,本文也认为同样翻译成“外观”比较好,当然,为了更好理解,可以是“服务外观”。即使如此,从私人角度,我更希望将其直呼为“服务定位器”、“服务代理”或者“服务别名”,实际上国外的很多人也是建议如此更名,只是Taylor在这件事上态度一反往常地强硬,所以也暂且不必强求。
通过下文,待实际了解了facade pattern具体是啥后,我想你会更好地理解为什么翻译为“外观模式”更贴切。
什么是facade pattern(“外观模式”的定义)
不论在现实世界还是编程世界,facade(外观)的目的就是给一个可能原本丑的、杂乱的东西,“披上”一个优美的、吸引人的外观、或者说面具,用中国的俗话就是:什么是外观?“人靠衣装马靠鞍”。基于此,facade pattern就是将一个或多个杂乱的、复杂的、不容易重构的class,添加上(或转换成)一个漂亮优雅的对接入口(interface),这样呢好让你更乐意、更方便地去操作它,从而间接地操作了背后的实际逻辑。
什么时候需要用facade pattern
facade pattern(“外观模式”)经常是用来给一个或多个子系统,来提供统一的入口界面(interface),或者说操作界面。
当你需要操作别人遗留下来的项目,或者说第三方的代码的时候。尤其是通常情况下,这些代码你不容易去重构它们,也没有提供测试(tests)。这个时候,你就可以创建一个facade(“外观”),去将原来的代码“包裹”起来,以此来简化或优化其使用场景。
说得再多,不如来几个例子直观:
示例一:在java中,通过facade操作计算机内部复杂的系统信息
假设我们有这么一些复杂的子系统逻辑:
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 {
public void startComputer() {
cpu.freeze();
memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE));
cpu.jump(BOOT_ADDRESS);
cpu.execute();
}
}
然后我们的客户,就可以很方便地来这样调用了:
class You {
public static void main(String[] args) {
Computer facade = new Computer();
facade.startComputer();
}
}
示例二:一个糟糕的第三方邮件类
假设你不得不用下面这个看上去很糟糕的第三方邮件类,尤其是里面每个方法名你都得停留个好几秒才能看懂:
interface SendMailInterface
{
public function setSendToEmailAddress($emailAddress);
public function setSubjectName($subject);
public function setTheEmailContents($body);
public function setTheHeaders($headers);
public function getTheHeaders();
public function getTheHeadersText();
public function sendTheEmailNow();
}
class SendMail implements SendMailInterface
{
public $to, $subject, $body;
public $headers = array();
public function setSendToEmailAddress($emailAddress)
{
$this->to = $emailAddress;
}
public function setSubjectName($subject)
{
$this->subject = $subject;
}
public function setTheEmailContents($body)
{
$this->body = $body;
}
public function setTheHeaders($headers)
{
$this->headers = $headers;
}
public function getTheHeaders()
{
return $this->headers;
}
public function getTheHeadersText()
{
$headers = "";
foreach ($this->getTheHeaders() as $header) {
$headers .= $header . "\r\n";
}
}
public function sendTheEmailNow()
{
mail($this->to, $this->subject, $this->body, $this->getTheHeadersText());
}
}
PHP有序表查找之插值查找算法示例这篇文章主要介绍了PHP有序表查找之插值查找算法,简单分析了插值查找算法的概念、原理并结合实例形式分析了php实
ThinkPHP整合datatables实现服务端分页的示例代码下面小编就为大家分享一篇ThinkPHP整合datatables实现服务端分页的示例代码,具有很好的参考价值,希望对大家有所帮
PHP实现APP微信支付的实例讲解下面小编就为大家分享一篇PHP实现APP微信支付的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小
PHP实现的多维数组排序算法分析这篇文章主要介绍了PHP实现的多维数组排序算法,结合实例形式对比分析了php针对多维数组及带有键名的多维数组进行
php+ajax实现无刷新文件上传功能(ajaxuploadfile)这篇文章主要为大家详细介绍了php结合ajaxuploadfile实现无刷新文件上传功能,具有一定的参考价值,感兴趣的小伙伴们
PHP的RSA加密解密方法以及开发接口使用本篇文章给大家详细介绍了PHP开发接口使用RSA进行加密解密方法,对此有兴趣的朋友可以学习下。