Oop 面向对象编程中的Facade

Oop 面向对象编程中的Facade,oop,design-patterns,Oop,Design Patterns,在OOP中,Facade是一个对象还是一个类?哪个更好 中的大多数示例都将Facade创建为一个对象,应该在使用前进行实例化 CarFacade cf = new CarFacade(); cf.start(); 它能被设计成这样吗 CarFacade.start(); 更新 Facade能促进单身吗?它有两个方面。您可以将其用作静态方法。比如说,在SpringSecurity中,我使用AuthenticationFacade访问当前登录的用户主体详细信息,如下所示Authenticatio

在OOP中,Facade是一个对象还是一个类?哪个更好

中的大多数示例都将Facade创建为一个对象,应该在使用前进行实例化

CarFacade cf = new CarFacade();
cf.start();
它能被设计成这样吗

CarFacade.start();
更新


Facade
能促进单身吗?

它有两个方面。您可以将其用作静态方法。比如说,在SpringSecurity中,我使用AuthenticationFacade访问当前登录的用户主体详细信息,如下所示<代码>AuthenticationFacade.getName()

还有其他一些实例,其中大多数人创建一个Facade实例并使用它。在我看来,两种方法都不优于另一种。而是取决于你的背景

最后,Facade可以使用
Singleton
模式来确保它只创建一个实例,并提供对它的全局访问点

  • 表示复杂子系统(模块)的高级API
  • 减少客户端代码依赖性

    这意味着您的客户机代码只使用facade,不使用facade 没有太多依赖于该外观后面的类

最好使用接口的实例,因为

  • 您可以替换它进行测试。例如,模拟立面所代表的子系统
  • 您可以在运行时替换它
当您使用静态方法时,您的客户机代码在编译时绑定到该方法实现。这通常是相反的

我说的“通常是相反的”,因为有使用静态方法的例子,但系统仍然可以扩展。例如

  • 静态加载方法只扫描类路径和查找服务实现。因此,将类和
    META-INF/services
    描述添加到类路径将添加其他可用的服务,而无需更改
    ServiceLoader
    的代码

  • 例如,Spring的
    AuthenticationFacade
    在内部使用
    ThreadLocal
    。这样就可以替换
    AuthenticationFacade
    的行为。因此,它也可以扩展


最后,我认为最好使用一个实例和接口,就像大多数其他类一样。

这个问题非常主观。我做出回应的唯一原因是,我查看了自己的一些代码,发现我在一个应用程序中以单例的形式编写了一个Façade,在另一个需要实例的应用程序中编写了几乎相同的Façade。我将讨论为什么我在各自的应用程序中选择了这些路线,以便评估我是否做出了正确的选择

@Rene Link已经解释了立面与开/关原则的对比。根据我个人的经验,你必须这样想:对象是否保持自身的状态?

假设我有一个包装Azure存储API for.NET()的外观

此外观包含有关如何根据存储API进行身份验证的信息,以便客户端可以执行以下操作:

Azure.Authenticate(username, password);
Azure.CreateFile("My New Text File", "\\FILELOCATION");
Azure.Authenticate(username, password)
Azure.CreateFile("My New Text File", "\\FILELOCATION");

Azure.Authenticate(username2, password2);
Azure.CreateFile("My Restrictied Text File", "\\RESTRTICTEDFILELOCATION");
Using (AzureFacade myAzure = Azure.Authenticate(username, password)) 
{
    Azure.CreateFile("My New Text File", "\\FILELOCATION"); // I will always know the username and password.
}
正如您在本例中看到的,我没有创建实例,我使用的是静态方法,因此遵循单例模式。虽然这使得代码更加简洁,但如果我需要使用与已提供的凭据不同的凭据对给定路径进行身份验证,我现在有一个问题,我必须执行以下操作:

Azure.Authenticate(username, password);
Azure.CreateFile("My New Text File", "\\FILELOCATION");
Azure.Authenticate(username, password)
Azure.CreateFile("My New Text File", "\\FILELOCATION");

Azure.Authenticate(username2, password2);
Azure.CreateFile("My Restrictied Text File", "\\RESTRTICTEDFILELOCATION");
Using (AzureFacade myAzure = Azure.Authenticate(username, password)) 
{
    Azure.CreateFile("My New Text File", "\\FILELOCATION"); // I will always know the username and password.
}
虽然这会起作用,但当我调用
Azure.ReadFile
时,很难确定身份验证失败的原因,因为我不知道什么用户名和密码可能已经从form2上的thread4传递到了singleton中(在哪里都找不到)。这是您应该使用实例的主要示例。这样做会带来更多好处:

Azure.Authenticate(username, password);
Azure.CreateFile("My New Text File", "\\FILELOCATION");
Azure.Authenticate(username, password)
Azure.CreateFile("My New Text File", "\\FILELOCATION");

Azure.Authenticate(username2, password2);
Azure.CreateFile("My Restrictied Text File", "\\RESTRTICTEDFILELOCATION");
Using (AzureFacade myAzure = Azure.Authenticate(username, password)) 
{
    Azure.CreateFile("My New Text File", "\\FILELOCATION"); // I will always know the username and password.
}
话虽如此,如果开发人员需要在Azure中以一种不知道Azure的用户名和密码的方法创建一个文件,该怎么办。一个很好的例子是定期连接Azure并执行一些多线程任务的应用程序。在所述应用程序中,用户设置到azure的连接字符串,并且使用该连接字符串执行所有多线程任务。因此,不需要为每个线程创建实例(因为对象的状态始终相同),但是,为了维护线程安全,您不希望在所有线程之间共享同一实例。这就是单例线程安全模式可能发挥作用的地方。(Spring的
AuthenticationFacade
根据@Rene-Link)这样我就可以做这样的事情(psudocode)


因此,在一个façade v。一个单体façade完全依赖于facade的预期应用程序,但是两者都肯定存在。

实例(您称之为object)和静态类之间的争论可以很容易地归结为:类是否持有某种状态?该类是否表示多个类中的一个?如果不是,则使用静态类。如果是,请使用实例。可能需要查看: