我读得越多,我就越困惑。
请注意,所有问题都与服务和外观如何适合MVC模式有关。
我的理解是,Facade不是超级智能的对象,它只是公开一个简单的界面/ api即可执行复杂操作的一种方式(例如:执行10美元的付款,这是一个涉及多个操作的复杂操作操作,但是这种复杂性可以通过外观来处理,外观将仅以特定顺序调用相应的对象...等)
现在,服务是一种对多个DAO进行调用以获取复杂数据结构的方式(我不太确定这一点,但是到目前为止,这是我所了解的)。
问题是,外观和服务之间有什么区别?归根结底,立面可以通过提供简单的界面来完美地访问多个DAO,以执行复杂的操作,并且服务似乎类似。
事务也是如此,我知道服务是开始事务的地方,但我同样感到它们也可以放在外观上,毕竟,外观也可以调用多个DAO。
所以哪个堆栈更有意义
控制器-门面-dao控制器-服务-dao
或许
controller-facadade-dao有时有时是controller-facade-service-dao?
一个服务是书面形式向外部系统的接口,如LDAP身份商店,支付网关或应用管理界面的一种方式。这是一种将外部系统视为有用服务的提供者的概念性方法,它可能具有内部行为,而不是要操作的被动块。
阿立面是结束了任何东西(包括服务),以很好地呈现它到另一部件的方法。在以下情况下通常使用外墙:
- 库或组件很复杂,您的应用程序只需要其中的一个子集。您的Facade向应用程序提供简化的API
- 您正在使用多个库或组件,并且需要对其进行统一,从而为应用程序提供一个统一的API
- 您使用的库具有复杂的设置或一组依赖关系,而Facade将所有内容打包在应用程序的上下文中。
真正令人困惑的一点是,您可以(而且经常这样做)在一个或多个服务上创建外观。服务是组件实际访问资源的方式,而Facade是简化组件的位(例如,选项的配置,连接等)。
如果您编写自己的DAO,则可能会根据需要创建服务,因此编写立面表示您做错了。如果DAO是由第三方构建的,并且比您的需求复杂,则可以使用该服务。
现在,服务是一种对多个DAO进行调用以获取复杂数据结构的方式(我不太确定这一点,但是到目前为止,这是我所了解的)。
我要说的是DAO本身就是一种设计模式,请参阅Wikipedia。
如果我们将DAO与服务进行对比,我们将:
- API级别:
- DAO:对属性的细粒度访问
- 服务:粗粒度访问服务
- 实现所在:
- DAO:主要在客户端上,但是在数据库中存储数据(无行为)
- 服务:主要在服务器上
- 接口如何调用
- DAO:客户端直接绑定到相同名称空间和JVM中的对象
- 服务:客户端只是网络,跨虚拟机或跨命名空间操作的存根
...外观可以通过提供简单的界面来完美地访问多个DAO,以执行复杂的操作,并且服务似乎也类似。
外墙可以包裹DAO层,但是我真的看不到这种有用的方式。很可能您需要一个API来访问对象的各个属性,遍历对象图等,而这正是DAO提供的。
交易也是如此,我知道服务是开始交易的地方...
绝对是因为事务是数据库和另一个组件或系统上提供的服务
...但是我同样感到它们也可以放置在立面上,毕竟,立面也可以称为多个DAO。
而且在许多方面,事务管理器服务是更复杂的后端实现的基础,它可以协调Web,应用程序,数据库和其他可识别事务的组件上的事务。但是,这已经被事务服务实现抽象化了。就我们用户而言,只有公共接口。
实际上,这就是这些设计模式的概念点-为用户提供适量的API,从而抽象了组件接口铁壁背后的实现复杂性。
所以哪个堆栈更有意义
控制器-门面-dao控制器-服务-dao
或许
controller-facadade-dao有时有时是controller-facade-service-dao?
- DAO是对数据库的一种服务,但实际上DAO本身就是一种设计模式。
- 如果您编写自己的DAO,则永远不需要外观。
因此正确的答案是:
- 控制器-dao
从字面上看,立面顾名思义就是指建筑物的正面。走过马路的人只能看到外墙,他们对里面的东西,布线,管道和其他复杂性一无所知。该面部隐藏了建筑物的所有复杂性,并显示了一个更简单友好的面部。
用软件的术语,facade通过提供更简单的界面来隐藏其背后的软件组件的复杂性,不具有其自身的功能,也不限制对subsysyem的访问。常用于面向对象设计。SLF4J是很好的例子-这是一个api,它是记录系统的简单外观,允许最终用户在部署时插入所需的记录系统。
服务是一个公共接口,提供对功能单元的访问,并且始终写入规范。它需要支持不同使用者所需要的通信合同(基于消息的通信,格式,协议,安全性,异常等等)。有流程服务-业务工作流封装,业务逻辑服务-规则/功能封装,数据服务-与实体的交互,数据访问管理,基础结构服务-实用程序功能,例如监视,日志记录和安全性。服务大部分是可重用的,未关联的,松散耦合的功能单元。
它们非常相似,但取决于您如何看待它。
我看到的区别是,外墙是由内而外设计的。您将研究子系统并设计外观以提供更简单的访问。服务是从外部设计的。您查看您的客户,定义合同并设计服务。
我对经典GoF Facade模式的理解是,它主要用于隐藏不良的设计。作为经验法则,我想说一个人只需要为旧代码编写一个Facade。
我还认为,这种模式之所以成为J2EE核心模式(会话外观),主要是因为EJB规范(至少为2.x)固有地导致不良的服务层设计。
因此,我对您的问题的答案是肯定的-外观实际上是首次未正确实施的服务。如果您需要从客户端代码中隐藏复杂性,通常意味着您仅设法提供一个库,而不是服务层。因此,在这种情况下,Facade实际上成为您的服务层。
另一方面(假设您有一个不错的域层),如果您确实需要通过单个方法调用(类似于宏/别名)提供生成复杂流的选项,通常最好将其放在应用程序层中,不在您的核心域中-请注意,我已将分层术语切换为域驱动设计,其中没有“数据访问”或“服务”层,但没有“应用程序”,“域”,“基础结构”。
通常,这些术语仅在其特定上下文中使用。
-
“外观”常见用法上下文:适用于应用程序复杂部分的简单API(例如第三方库)
-
“服务”上下文:解锁并显示系统中的业务实体。(SOA,DAO,安全性等)
您可以将模式视为一种不断发展的语言。每种模式都有自己的历史和环境似乎永远不是完美的结局。有时,可以同时将类视为“服务和外观”,有时则不能。
例如:由于上下文错误,因此以术语“服务”调用第三方API可能被视为滥用。
FACADE是一种设计模式,可以解决子系统中许多接口需要统一接口的问题,因此它定义了更高级别的接口,使子系统更易于使用。
但是,SERVICE提供对资源或一组接口/对象的访问,并且不一定会简化这种访问。因此,您可以采用立面模式来更好地设计服务,从而可以节省客户端的使用方法。
一个服务接口通常代表企业的关注:执行某些操作(S)和/或获得一些信息。对于服务提供商来说,将其服务实现为内部后端服务的基础并不是没有道理的-您永远不会看到这一点。
您的外观可能会包装一些常规接口,其中可能包括服务接口。
例如,您可能具有一个银行帐户的服务接口(操作:银行转帐),并为您的本地会计记录提供了本地API(我转帐)。您可能会通过“移动资金”操作引入外观,该操作使用银行的服务界面并管理您的本地支票簿。
首先要注意的是,设计模式是对标准解决方案中常见(设计)问题的描述。在某些情况下,有几种方法可以满足所有要求(例如,Iterator和Singleton模式具有大量不同的实现;例如,检查工作Alexandrescu
并将其与标准GoF解决方案进行比较)。 ),并且在某些情况下,具有相同(代码)解决方案的模式会有所不同(例如,比较GoF书中Composite和Decorator模式的类图)。
根据GoF,Facade模式的目的是(字面意思):
为子系统中的一组接口提供统一的接口。Facade定义了一个更高级别的界面,使子系统更易于使用。
服务旨在为用户提供具有给定功能的单个更高级别的界面。这不一定使它成为一个外观,因为严格来讲,服务并不是按照定义unified interface to a set of interfaces in a subsystem.
但是我们可以做得更好
您的问题是模式是否“相似”。如果当模式A等于B而模式B等于A时我们认为它们“相似”,那么我们应该回答两个问题:
问题1:是Service
一个Facade
?服务肯定应该公开功能,并且绝对是公开此功能的单个接口。功能通常被分解成很小的部分,因此,服务符合立面的基本要求。换句话说:面对将底层接口公开为统一的“服务”接口的问题,外观模式符合要求并用于解决服务问题。答案是肯定的。
问题2:是Facade
一个Service
?服务通常被设计为可重用的,未关联的,松散耦合的功能单元。考虑组件之间的通信对于服务很重要,因为它们通常依赖于TCP / IP接口,例如SOAP或WCF。这也意味着通常会重写功能以services
更紧密地适应该范式,从而增加了对模式性能要求的隐式驱动。外墙没有此额外要求。换句话说:外观不是服务。
确切地说,这些概念是密切相关的,但并不相同。
但是我们可以做得更好
这种思路引发了一个问题,即服务是否是外观的扩展版本?这是一项服务是否满足立面的所有要求并在此之上进行扩展。
如果您仔细阅读GoF的描述,答案是肯定的,即:如果满足一个条件:服务必须公开子系统。实际上,我认为这种情况通常会成立,或者您正在过度设计服务-尽管严格地说,我认为这不是硬性限制。
在尝试回答之前,让我先澄清一下:企业应用程序中有三类不同的东西:Facade,Service Layer和Remote Facade。
外观-在包装子系统时,仍然是一个对象,UI(MVC)应用程序通常位于同一进程中。因此,通信以通常的OO方式完成:调用方法,读取属性,侦听事件。
服务层-当业务逻辑层变得成熟且太复杂而使MVC无法直接与之交互时,则将服务层置于它们之间。服务层是MVC用作业务逻辑包装的API。它不是远程的,并且不需要使用DTO,因为通信中没有电线。
远程Facade-(简而言之,是任何远程服务)这是Facade和Service Layer的混合体。当您想在系统(我们称为Facade)上公开某种包装作为分发边界时,Remote Facade就开始存在。原因之一可能是允许多个UI(MVC)应用程序使用相同的Remote Facade。
--
比较:
正面与服务层:它们相似,因为它们都包装了子系统。区别在于,服务层更面向UI(MVC)应用程序需求,并公开功能以简化使用业务逻辑的工作。另一方面,Facade正在公开简化业务逻辑的功能,但不一定简化与UI(MVC)应用程序的通信。
外观与远程外观(服务?):绝对不同,因为远程外观必须使用DTO作为通信消息。如果您仍想将远程Facade用作常规对象(属性,事件),则需要某种代理。但是代理仍然会使用DTO到真实对象,即远程外观。
--
可能的流程:
controller-facade-dao
-令人怀疑,但仍然可能。外墙通常不用于仅包装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
-我确定您可以翻译。
--
请记住,服务(或远程立面)可以存在于流中的任何位置。这仅取决于您的发行需求。
是的,外观和服务并非完全无关。有时我们将Service层实现为Facade,这样客户端就不必担心服务的许多细节了。服务的调用/接口越简单,客户端代码就越简单。
马丁·福勒(Martin Fowler)说...
服务层从连接客户端层的角度定义了应用程序的边界[Cockburn PloP]及其可用操作集。它封装了应用程序的业务逻辑,控制事务并在其操作的实现中协调响应
因此,服务层有时用作Facade。
重要的是“上下文”。外观和服务没有冲突。
首先,我从未听说过MVC中的“服务”和“外观”。
当人们谈论服务时,它更多是关于向外界提供对业务有意义的操作的系统或组件。有时您可能会看到与“工作单元”(以及交易)相关的“服务”。
服务还用于某些分层应用程序的上下文中:我们在DAO之上有Service,为此,Service将通过DAO访问数据,而业务逻辑则放在Service层中,类似这样。
门面通常用于设计模式的上下文中,重点是“隐藏复杂的操作并将其公开为简单的操作”。
Facade可能是或可能不是服务(Facade中的操作可能不代表工作单元,但它仍然是有效的Facade),类似地,Service可能会也可能不是Facade(Service可能不会隐藏任何复杂的内容)操作,但仍然是服务)。
同样,重要的是“上下文”。
例如,当您谈论应用程序的分层时,说“ XXX是访问DAO的外观”是不合理的。同样,如果您在谈论“设计方法”,则更合理地说“ XXX是多个后端的立面”而不是在此处将其称为“服务”(尽管XXX实际上是一种服务)。
外观和服务层具有相似之处,但是两者都有两个不同的含义。让我用一个简单的例子对此进行解释。
想象我们被要求创建新的业务应用程序。这需要创建一个签到应用程序,但具有更多的增值功能和会员卡功能。
可以说,如果用户希望使用应用程序,则应支持Facebook和Foursquare签入功能。非常需要此功能,因为某些用户不愿意使用执行相同功能的多个应用程序或摆脱社交连接。
要获得较高的建议,请参考以下链接上的示例api https://docs.google.com/file/d/0B3v8S0e-PvVpdWFJOVhqc1d2SHc/edit?usp=sharing
位于ABC外观上的检入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,可能是其他内部服务等,以便在应用程序中完成商家签入。
文章标签:design-patterns , facade , java , model-view-controller , spring
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!
评论已关闭!