服务和外观的角色是否相似?

时间:2013-02-23 07:40:33

标签: java spring model-view-controller design-patterns facade

我读的越多,我就越困惑。

请注意,所有问题都与服务和外观如何适应MVC模式有关。

我的理解是Facade不是一个超级智能对象,它只是一种暴露简单接口/ api来执行复杂操作的方式(例如:执行10 $付款,这是一个复杂的操作,涉及到一些操作,但这种复杂性可以通过一个外观来处理,它只会以特定的顺序调用相应的对象......等等。)

现在,服务是一种执行对几个DAO的调用以获得复杂数据结构的方法(我对此不太了解,但这是我目前所理解的)。

问题是,外观与服务有什么区别?在一天结束时,外观可以完美地访问几个DAO,以便通过提供简单的界面来执行复杂的操作,并且服务似乎是类似的。

交易也是如此,我知道服务是开始交易的地方,但我同样觉得它们也可以放在外墙上,毕竟外立面也可以调用几个DAO。

那么哪个堆栈更有意义

控制器门面-DAO 控制器服务-DAO

或者

controller-facadade-dao,有时是controller-facade-service-dao ??

11 个答案:

答案 0 :(得分:39)

服务是一种将接口写入外部系统的方法,例如LDAP身份存储,支付网关或应用程序管理界面。这是一种概念性的方式,将外部系统视为有用服务的提供者,可能具有内部行为,而不是被操作的被动集合。

facade 是一种包装任何东西(包括服务)的方式,可以很好地呈现给另一个组件。外墙通常用于:

  • 库或组件很复杂,您的应用程序只需要它的一部分。您的Facade向应用程序提供了简化的API
  • 您正在使用多个库或组件,需要统一它们,向应用程序提供合并的API
  • 您使用的库具有复杂的设置或一组依赖关系,并且Facade在您的应用程序的上下文中包含所有这些。

令人困惑的是,您可以(通常会)在一个或多个服务上创建外观。服务是组件实际访问资源的方式,而Facade是简化组件的位(例如选项配置,连接等)。

如果您编写自己的DAO,您可能会根据需要创建服务,因此编写外观表明您做错了。如果DAO是由第三方构建的,并且比您的需求更复杂,那么然后就可以使用该服务。

  

现在,服务是一种对多个DAO执行调用以获取复杂数据结构的方法(我对此不太了解,但到目前为止我理解的是这样。)

我会说DAO是一个独立的设计模式 - see wikipedia

如果我们将DAO与服务进行对比,我们有:

  • API级别:
    • DAO:细粒度访问属性
    • 服务:粗略访问服务
  • 实施在哪里:
    • DAO:主要在客户端,但在数据库中存储数据(没有行为)
    • 服务:主要在服务器上
  • 如何调用接口
    • DAO:客户端直接绑定到同一名称空间和JVM
    • 中的对象
    • 服务:客户端只是网络,跨vm或跨命名空间操作的存根
  

...外观可以完美地访问几个DAO,以便通过提供简单的界面来执行复杂的操作,并且服务似乎是类似的。

Facade 可以包装DAO层,但我并没有真正看到这种情况以有用的方式发生。很可能你需要一个API来访问对象的各个属性,遍历对象图和类似的东西,这正是DAO提供的。

  

交易也是如此,我知道服务是开始交易的地方......

当然,因为事务是由数据库和另一个组件或系统提供的服务

  

......但我同样觉得它们也可以放在外墙上,毕竟外立面也可能会叫几个DAO。

在许多方面,事务管理器 service 是一个更复杂的后端实现的外观,协调Web,应用程序,数据库和其他事务感知组件上的事务。 然而这已经被事务服务实现抽象掉了。就我们而言,用户而言,只有公共接口。

事实上,这是这些设计模式的概念点 - 为用户提供适量的API,抽象出组件界面背后的实现的复杂性。

  

那么哪个堆栈更有意义

     

controller-facade-dao controller-service-dao

     

或者

     

controller-facadade-dao,有时是controller-facade-service-dao ??

  1. DAO是对数据库的一种服务,但实际上DAO本身就是一种设计模式。
  2. 如果您编写自己的DAO,则永远不需要外观。
  3. 因此,正确的答案是:

    • controller - dao

答案 1 :(得分:15)

从字面上看,Facade顾名思义就是建筑的正面。走过马路的人只能看到立面,他们对里面的东西,布线,管道和其他复杂性一无所知。面部隐藏了建筑的所有复杂性,并展现出更简单友好的面孔。

在软件方面, facade通过提供更简单的界面隐藏其背后的软件组件的复杂性,不具有自己的功能,并且不限制对substsyem的访问。常用于面向对象设计。 很好的例子是SLF4J - 它是一个api,它是日志系统的简单外观,允许最终用户在部署时插入所需的日志记录系统。

服务是公共接口,它提供对功能单元的访问,并始终写入规范。它需要支持不同消费者需要的通信合同(基于消息的通信,格式,协议,安全性,异常等)。 有流程服务 - 业务工作流的封装,业务逻辑服务 - 规则/功能的封装,数据服务 - 与实体的交互,数据访问管理,基础设施服务 - 监控,记录和监控等实用功能。安全。服务主要是可重用,无关联,松散耦合的功能单元。

它们很相似,但取决于你如何看待它。

  

我看到的不同之处在于,Facades的内部设计。你看   在子系统和设计一个外观,以提供更简单的访问。服务   在外面设计。你看你的客户/客户定义一个   签订合同并设计服务。

答案 2 :(得分:2)

我对古典GoF Facade模式的理解是,它主要是为了隐藏糟糕的设计。根据经验,我会说只需要一个遗留代码的Facade。

我还认为这种模式成为J2EE核心模式(Session Facade),主要是因为EJB规范(至少高达2.x)固有地导致了糟糕的服务层设计。

因此,我对您的问题的回答是 - 外观实际上是第一次未正确实施的服务。如果您需要隐藏客户端代码的复杂性,通常意味着您只设法提供库,而不是服务层;因此,在这种情况下,Facade实际上成为您的服务层。

另一方面(假设你有一个不错的域层),如果你真的需要提供使用单个方法调用产生复杂流的选项(类似于宏/别名),这通常会更好地放在应用层而不是你的核心域 - 注意到我已经将分层术语切换到域驱动设计,其中没有“数据访问”或“服务”层,而是“应用程序”,“域”,“基础设施” “

答案 3 :(得分:2)

FACADE是一种设计模式,它解决了需要为子系统中的许多接口提供统一接口的问题,因此它定义了一个更高级别的接口,使子系统更易于使用。

但是,服务提供对资源或一组接口/对象的访问,并且可能不一定简化这种访问。因此,您可以使用外观模式来更好地设计您的服务,以便您可以保存客户端,了解如何构建以使用它。

答案 4 :(得分:1)

通常这些术语仅用于其特定的上下文中。

  • 'Facade'常用用法上下文:应用程序复杂部分的简单API(如第三方库)

  • '服务'上下文:解锁并展示系统中的业务实体。 (SOA,DAO,安全等)

您可以将模式视为一种演变的语言。它似乎永远不会是完美的结束每个模式都有它自己的历史和背景。有时课程可以同时被视为服务和外观,有时不是。

例如:由于错误的上下文,通过术语“服务”调用第三方API可能被视为滥用。

答案 5 :(得分:1)

服务接口通常表示业务问题:执行某些操作和/或获取一些信息。服务提供商将其服务作为内部后端服务的外观实现是不合理的 - 您永远不会看到这一点。

您的 facade 可能会包含一些通用接口,其中可能包含服务接口。

例如,您可能拥有银行帐户的服务界面(操作:银行汇款),以及本地会计记录的本地API(我汇款)。您可以通过“移动货币”操作引入外观,该操作使用银行的服务界面并管理您的本地支票簿。

答案 6 :(得分:1)

是的,门面和服务并非完全不相关。有一段时间我们将服务层实现为Facade,这样客户就不会对服务的许多细节感到困扰。服务的调用/接口越简单,客户端代码就越简单容易。

Martin Fowler说......

  

服务层从连接客户端层的角度定义应用程序的边界[Cockburn PloP]及其可用操作集。它封装了应用程序的业务逻辑,控制事务并协调其操作实现中的响应

因此服务层有时被用作Facade。

Ref

答案 7 :(得分:1)

首先要注意的是,设计模式是对标准解决方案的常见(设计)问题的描述。在某些情况下,有几种方法可以满足所有要求的方式解决问题(例如,Iterator和Singleton模式有大量不同的实现; f.ex.检查Alexandrescu的工作并进行比较使用标准的GoF解决方案)并且在某些情况下,存在具有相同(代码)解决方案的不同模式(例如,比较复合的类图和GoF书中的装饰器模式)。

根据GoF,Facade模式的目的是(字面引用):

  

为子系统中的一组接口提供统一接口。 Facade定义了一个更高级别的界面,使子系统更易于使用。

服务旨在为用户提供具有给定功能的单个更高级别接口。这并不一定使它成为一个外观,因为服务严格来说不是定义为unified interface to a set of interfaces in a subsystem.

但我们可以做得更好

你的问题是模式是否“相似”。如果我们认为当模式A等于B而模式B等于A时它们是“相似的”,那么我们应该回答2个问题:

问题1:ServiceFacade?服务绝对应该公开功能,绝对是一个公开此功能的单一界面。功能通常被分解成很小的部分,所以是的,服务符合外观的基本要求。换句话说:面对将底层接口暴露为统一“服务”接口的问题,外观模式符合要求并用于解决服务问题。答案是

问题2:FacadeService?服务通常设计为可重复使用,无关联,松散耦合的功能单元。考虑组件之间的通信对于服务很重要,因为它们通常依赖于TCP / IP接口,例如SOAP或WCF。这也意味着通常会重新编写功能以更紧密地适应services范例,这会为模式添加隐含的由性能驱动的需求。外墙没有这个额外的要求。换句话说:外观不是服务

确切地说,这些概念密切相关,但不相同。

但我们可以做得更好

如果服务是门面的扩展版本,这种思路会引发一个问题?如果服务满足立面的所有要求并在此基础上进行扩展。

如果您仔细阅读GoF的描述,答案是肯定的,即:如果满足一个条件:服务必须公开子系统。实际上,我认为这种情况通常存在,或者你过度设计你的服务 - 尽管严格来说我认为这不是一个严格的限制。

答案 8 :(得分:1)

在我尝试回答之前,让我澄清一下:企业应用程序中有三个不同的东西 - Facade 服务层远程外观

Facade - 在包装子系统时,仍然是一个对象,而UI(MVC)应用程序通常存在于同一个进程中。因此,通信以通常的OO方式完成:调用方法,读取属性,监听事件。

服务层 - 当业务逻辑层变得成熟且过于复杂而MVC无法直接与其进行交互时,就会在它们之间放置服务层。 Service Layer是MVC用作业务逻辑包装的API。它不是远程的,不需要使用DTO,因为通信中不涉及电线。

远程门面 - (简称,任何远程服务)这是Facade和Service Layer的混合体。当您希望在系统上公开某种包装器(我们称之为Facade)作为分布边界时,远程Facade会启动。其中一个原因可能是允许多个UI(MVC)应用程序使用相同的远程外观。

-

<强>比较

Facade 服务层:它们相似,因为它们都包装了子系统。区别在于服务层更面向UI(MVC)应用程序需求,并公开函数以简化业务逻辑的使用。另一方面,Facade公开了简化业务逻辑的功能,但不一定简化与UI(MVC)应用程序的通信。

外观远程外观(服务?):完全不同,因为Remote Facade必须使用DTO作为通信消息。如果您仍想将它用作常规对象(属性,事件),远程Facade将需要某种代理;但代理人无论如何都会将DTO用于真实对象,即远程门面。

-

可能的流程:

controller-facade-dao - 怀疑,但仍有可能。 Facade通常不用于包装DAL。作为子系统,应该有更成熟的东西。但是,如果外观是业务逻辑的一部分,那么是的,这是可能的。必须更加强调子系统。对我来说,DAL包装不足以称之为Facade。

controller-service-dao - 绝对可能。许多远程服务通过DAL直接与数据库协同工作。

controller-facade-service-dao - 也许,如果您将服务视为一个子系统。

我会再添加一个有意义的内容:

controller-service [layer]-facade (part of business)-subsystem (e.g. accounting, business on its own)-dao - 我相信你可以翻译一下。

-

请记住,服务(或远程外观)可以存在于流中的任何位置。这只取决于您的分销需求。

答案 9 :(得分:0)

重要的是“背景”。门面和服务没有冲突。

首先,我从未在MVC的背景下听说过“服务”和“门面”。

当人们谈论服务时,更多的是关于向外界提供有商业意义的行为的系统或组件。您有时可能会看到与“工作单位”(以及交易)相关的“服务”。

服务也用于应用程序的一些分层方法:我们在DAO之上有Service,Service将通过DAO访问数据,业务逻辑放在Service层中,就像那样。

Facade通常用于设计模式的上下文中,重点是“隐藏复杂的操作并将其作为一个简单的操作公开”。

Facade可能是也可能不是服务(Facade中的操作可能不代表工作单元,但它仍然是有效的外观),类似地,服务可能是也可能不是Facade(服务可能不是隐藏任何复杂的操作,但它仍然是一个服务。)

同样,重要的是“背景”。

例如,当您谈论应用程序的分层时,说“XXX是访问DAO的外观”是完全不合理的。同样,如果你在谈论“设计方法”,那么说“XXX是多个后端的外观”而不是在这里称它为“服务”更合理(尽管XXX实际上是一种服务)。

答案 10 :(得分:0)

Facade 服务层有一些相似之处,但它们都有两个识别含义。让我用一个简单的例子解释一下。

想象一下,我们被要求创建新的业务应用程序。这需要创建一个签到应用程序,但具有更多增值功能和会员卡功能。

让我们假设应用程序应该支持Facebook和Foursquare签到功能,如果用户希望使用。此功能非常需要,因为有些用户不愿意使用多个执行相同功能的应用程序或摆脱社交连接。

要获得高级别的想法,请参阅以下链接https://docs.google.com/file/d/0B3v8S0e-PvVpdWFJOVhqc1d2SHc/edit?usp=sharing

上的示例API

位于ABC facade的上面的登记API就是使用Facade的一个例子。

它有我们的服务API以及基于客户选择的facebook和foursqure登记功能。 Facebook和foursqure API可以具有特定的实现(SOAP,Restful等)和安全性(OAuth等)要求等。

满足其中一个API(facebook,foursqure)要求需要完成不同的任务集。在我们的登记要求中,这些将是不同的子系统。

因此,Facade的简单用法是满足由一个简单方法触发的几个子系统

但是如果我们考虑我们自己的API,它是位于MngCheckinSvc的签入API。这是服务层API 。这是包含我们的应用程序的签入要求的API。这是API提供来自您的MngCheckinSvc的公共访问,以处理应用程序的签入要求。

这将具有复杂的内部行为,但其中大多数仍将是特定于应用程序的逻辑实现。

此API(MngCheckinSvc.checkin(....))可能访问不同的DAO集,内部API,可能是其他内部服务等,以便在应用程序中完成商家签到。