外观模式门面模式:外部与一个子系统的通信必须通过统一的外观对象进行,为子系统中的一组接口提供一致的接口,外观模式定义使该子系统更易于使用的高级接口。外观模式,又称门面模式,是一种对象结构模式。Laravel中我们常用的Route、Redis、Auth等Facades就是外观模式的具体实现。Laravel中设计了多个外观类,每个外观类都继承自一个统一的抽象外观类。Facade类访问其背后的子系统的底层方法。对于新的业务需求,不修改原来的外观类,而是增加一个新的具体外观类,并将新的子系统对象与新的具体外观类相关联,修改配置文件,达到不修改源码和更换外观类的目的。下面是一个简单外观模式的例子,没有引入抽象外观类。在介绍LaravelFacades的文章中,我们会看到Laravel提供了一个抽象的外观类,这样我们就可以方便地根据需要添加新的子系统的外观类,并允许外观类被适当地代理到其对应的子系统(或服务)。Schema结构Facade模式包含以下角色:FacadeFacade角色SubSystem子系统角色代码示例operation();}}classFacade{private$systemA;私人$系统B;公共函数__construct(){$this->systemA=newSystemA;$this->systemB=newSystemB;}publicfunctionoperation(){$this->systemA->operationA();$this->systemB->operationB();}}classSystemA{publicfunctionoperationA(){//}}classSystemB{publicfunctionoperationB(){//}}模式分析根据“单一职责原则”,一个系统在软件中分为若干个子系统有利于降低整个系统的复杂度。一个共同的设计目标是最小化子系统之间的通信和相互依赖。实现这一目标的方法之一是引入外观对象,它提供对子系统的访问。提供简单的单一入口。-外观模式也是“迪米特定律”的体现。通过引入新的外观类,可以降低原有系统的复杂度,降低客户端类与子系统类之间的耦合度。-门面模式要求子系统外部和子系统内部的通信通过统一的门面对象进行,门面类将客户端与子系统内部的复杂性分离,让客户端只需要处理外观对象而不是与子系统内的许多对象交互。-门面模式的目的是降低系统的复杂度。-Appearance模式大大提高了客户端的便利性,使客户端无需关心子系统的工作细节,可以通过appearance角色调用相关功能。缺点外观模式的缺点不能很好地限制客户使用子系统类。如果对客户访问子系统类的限制太多,可变性和灵活性就会降低。在不引入抽象门面类的情况下,增加一个新的子系统可能需要修改门面类或客户端的源代码,违反了“开闭原则”。模式扩展一个系统有多个外观类在外观模式中,通常只需要一个外观类,而且这个外观类只有一个实例,也就是说它是一个单例类。很多时候,为了节省系统资源,外观类一般设计成单例类。当然,这并不是说整个系统只能有一个外观类。一个系统中可以设计多个外观类,每个外观类负责与一些具体的子系统进行交互,为用户提供相应的业务功能。不要试图通过外观类向子系统添加新的行为。不要通过继承外观类向子系统添加新行为。这种做法是错误的。外观模式的目的是为子系统提供集中和简化的通信渠道,而不是为子系统添加新的行为。新行为的增加应该通过修改原有的子系统类或者增加一个新的子系统类来实现,不能通过门面类来实现。抽象外观类的引入最大的缺点就是违反了“开闭原则”。添加新子系统或移除子系统时,需要修改外观类。这个问题可以通过引入一个抽象的外观类在一定程度上得到解决。客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有的外观类,而是相应地增加一个新的具体外观类,并将新的具体外观类与新的子系统对象相关联。同时,不修改源码,而是通过修改配置文件来代替。外观类的目的。总结在外观模式下,外部与子系统的通信必须通过统一的外观对象进行,外观对象为子系统中的一组接口提供了一致的接口。外观模式定义了一个高层接口,使得子系统更易于使用。外观模式,又称门面模式,是一种对象结构模式。门面模式包含两种角色:门面角色是在客户端直接调用的角色。在门面角色中,可以知道相关(一个或多个)子系统的功能和职责,它委托所有从客户端发送的请求。到对应的子系统,传递给对应的子系统对象进行处理;软件系统中可以同时存在一个或多个子系统角色,每个子系统可能不是一个单独的类,而是类的集合,它实现了子系统的功能。门面模式要求一个子系统外部与其内部的通信通过一个统一的门面对象进行,门面类将客户端与子系统内部的复杂性隔离开来,使得客户端只需要与门面打交道objectinsteadof子系统中的许多对象相互处理。外观模式的主要优点是对客户端屏蔽了子系统组件,减少了客户端处理的对象数量,使子系统更易于使用,实现了子系统与客户端的松耦合关系,减少了大型软件系统的复杂性。编译依赖简化了系统在不同平台之间移植的过程;它的缺点是不能很好地限制客户使用子系统类,而且在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违反了“开闭原则”。外观模式的适用场景包括:为复杂的子系统提供简单的界面;客户端程序与多个子系统之间存在较大的依赖关系;在层次结构中,需要定义系统中每一层的入口,使层与层之间没有直接关系。本文已收录在Laravel源码学习系列文章中,欢迎访问阅读。
