建立服务层有多重要?


68

我开始按3层(DAL,BL,UI)构建应用程序[它主要处理CRM,一些销售报告和库存]。

一位同事告诉我,我必须转向服务层模式,开发人员应从他们的经验中学到服务模式,这是设计大多数应用程序的更好方法。他说,将来以这种方式维护应用程序会容易得多。

就个人而言,我觉得它只是使事情变得更加复杂,我看不出有什么好处可以证明这一点。

这个应用程序确实有一个额外的小部分ui,它使用了一些(但只有少数)桌面应用程序功能,因此我确实发现自己在复制一些代码(但不很多)。仅仅由于某些代码重复,我不会将其转换为面向服务的,但是他说我还是应该使用它,因为总的来说,这是一个非常好的架构,为什么程序员如此热衷于服务?

我试图用谷歌搜索它,但是我仍然很困惑,无法决定该怎么做。

Answers:


58

马丁·福勒(Martin Fowler)的著作“企业体系结构模式”指出:

较容易回答的问题可能是何时不使用它。如果您的应用程序的业务逻辑仅具有一种客户端(例如,一个用户界面),并且用例响应不涉及多个事务资源,则可能不需要服务层。[...]

但是,一旦您构想出第二种客户端或用例响应中的第二种交易资源,就从一开始就在服务层中进行设计就值得了。

服务层提供的好处是,它定义了一组可供不同客户端使用的通用应用程序操作,并协调每个操作中的响应。如果您的应用程序具有不止一种类型的客户端,并且会使用其业务逻辑,并且具有涉及多个事务资源的复杂用例,那么在服务层中包含托管事务是有意义的。

使用CRM,销售和库存,将有许多CRUD类型的用例,其中几乎总是与服务层操作一对一对应。对域对象的创建,更新或删除的响应应通过服务层操作进行原子协调和事务处理。

拥有服务层的另一个好处是可以将其设计为本地或远程调用,或同时为两者而设计-并为您提供了这样做的灵活性。该模式为封装的应用程序业务逻辑实现以及各种客户端以一致的方式对该逻辑的调用奠定了基础。这意味着您还可以减少/删除代码重复,因为您的客户端共享相同的通用服务。您还可以潜在地降低维护成本-因为当您的业务逻辑更改时,您(通常)只需要更改服务,而不必更改每个客户端。

总而言之,使用服务层是很好的-而且-我想在您提供的示例中,因为听起来您有多个业务逻辑客户端。


2
有趣的是,马丁·福勒(Martin Fowler)主张对本地和远程调用使用相同的接口,认为远程调用中的巨大性能差异迫使使用更粗糙的接口。
psr

我不太理解您的段落With CRM, Sales and Inventory there will be a lot of CRUD-type use cases of which there is almost always a one-to-one correspondence with Service Layer operations-如果全部是关于多个UI的,那么CRUD如何进入这里?而且,即使CRUD与服务配合得很好,如果我不需要多个UI,如果我理解正确的话,我还是不会建立服务层,我真的希望我这样做是因为我更喜欢保持简单(服务层是弄乱我的经验)
BornToCode 2012年

4
在那种情况下,很少会有一个客户可以利用它。如果您只有一个UI,我会想到仍然需要服务层的两个原因:安全性和可重用性。典型的企业设置将使UI应用程序可用于外部客户端,而您的服务层仅在网络中可用。因此,Web服务器会将工作延迟到网络的锁定部分。在销售示例中,如果您从网站获取销售并扩展到eBay或Amazon,则可能会重复使用。现在,您只有一个UI,但有多个客户端。
菲尔·帕特森

5
只是添加来自@PhilPatterson的评论。多个客户端并不仅仅是基于UI。考虑Web服务或库-它们也可以是客户端。您的前端UI可能会使用服务层以及您打包的软件服务,并允许其他人使用。
Deco 2012年

您可以提供一个服务层示例吗?
user962206 2013年

34

添加服务层,因为您已经评估了该想法并得出了最佳方法:好的

添加服务层,因为这是所有很酷的孩子正在做的事情:不好

如果您的直觉说您不需要,那么就不要做。

在过去的十年左右的时间里,编程世界中最令人失望的发展之一是,它变得令人讨厌地以“时尚”为导向,人们追随潮流和潮流,就像他们是本季的鞋子一样。不要陷入陷阱。因为下个赛季“每个人”都会告诉您,您应该以其他方式进行设计。

服务层没有错也没有错-这是一种特殊的方法,应该根据其针对项目的技术优势来评估其适用性。不要因为自己的判断而被迫用他人的观点来代替。


27
这根本没有涉及主题,它只是对开发实践作了概括性的声明/证明,用几句话代替后,就可以应用于该站点上的几乎任何问题。从阅读这个答案,我甚至不相信,你知道一个服务层到底是什么
亚伦诺特,2012年

12
当然可以将其应用于其他问题……并不能使它不那么真实。事实既不是你,也不是我有必要陈述他在他的项目中需要什么的环境,因此告诉他是他需要,还是不他不需要,只是一种毫无根据的猜测和不专业。OP在这里需要的是一些道义上的支持,以做出他知道正确的决定。
2012年

5
@Aaronaught不管答案的正确性,他实际上仍在回答主要问题“服务层有多重要?”。他声称根本没有必要,而且可能只是一种时尚。如果您不同意答案,请投下反对票。
maple_shaft

2
@GrandmasterB我认为时尚在软件开发中是很好的。大多数开发人员太过新鲜或能力不足,无法做出明智的设计和体系结构决策。我们仍然希望他们能像工作软件一样,因此,比起几年前我们在所有工作上都采用牛仔代码的方式,让他们跳上潮流并与糟糕的设计选择保持一致是更可取和可维护的。不了解或欣赏。
maple_shaft

10
@maple_shaft只是为了澄清,我并不是说服务层是一种时尚。我是说,根据问题的提出方式,他的同事似乎有一些时髦/时尚/潮流的行为,促使他使用他认为在他的项目中不屈服的架构。我在回答中明确指出,我仅将服务层(或任何其他概念)视为-中立的概念,其适合性应根据各自项目的价值进行评估。当自己的判断表明他们没有需要时,不应使用/使用它们。
2012年

22

创建服务层的决定有很多因素。由于以下原因,我过去创建了服务层。

  1. 需要由多个客户端重复使用的代码。
  2. 我们拥有有限许可的第三方库。
  3. 需要集成的第三方指向我们的系统。
  4. 集中重复的业务逻辑。

情况1:您正在创建需要由众多不同客户端使用的基本功能。服务层为不同的客户端内置了功能,可以立即使用您提供的功能。

情况2:您通常将代码托管在应用程序空间中,但是您使用的许可证有限的第三方库。在这种情况下,您拥有想在任何地方使用的资源,但是数量有限。如果将其托管在服务背后,则整个组织都可以从其应用程序中使用它,而不必为每个托管主机购买许可证。

情况3:您正在构建第三方与您交流的功能。在您的示例中,您可以设置一个库存端点,以允许供应商将有关传入产品装运的消息传递给您。

案例4:您在整个企业范围内分析了代码,发现独立的团队创建了同一件事(只是实现方式略有不同)。通过服务层,您可以选择最佳方法,现在,您可以通过让他们加入服务,在所有团队中实施相同的过程。集中逻辑的另一个好处是发现错误时。现在,您可以一次部署此修复程序,并且所有客户端都可以同时享受这一好处。

所有这些都说对服务层有潜在的负面影响。

  1. 增加系统复杂性。在以前只有一个应用程序要调试的地方,现在只有两个。生产问题需要检查客户端应用程序设置,服务应用程序设置,或正确设置客户端和服务器应用程序之间的通信问题。如果您以前从未做过,这可能会很棘手。
  2. 一分失误。如果服务中断,则所有客户端都会受到影响。如果不以这种方式部署代码,则风险可能会更低(尽管有许多方法可以减轻这种风险)。
  3. 版本控制可能更难。当您有一个使用服务部署应用程序的应用程序时,可以在两个应用程序之间同时进行更改。如果现在有多个客户端,则必须管理谁在V1上,谁在V2上,并协调V1的删除(一旦您知道每个人都已更新到V2)。

要点是,使您的系统服务导向并非总是灌篮。以我的经验,这通常是一个好主意(我倾向于以这种方式构建应用程序),但这不是自动决定。最后,您需要权衡利弊,并做出适合您情况的决定。


2
+1感谢您提供的翔实答案。我真的怀疑天气是否会接受您的答案或Deco的答案。最终,由于我不太有经验,我决定选择最能被接受的答案。我仍然觉得你的答案值得更多的投票。无论如何,我非常感谢您分享您的知识和经验。谢谢!
BornToCode 2012年

1
别客气!从这两个答案中脱颖而出的主要观点是,这(主要是)通过让多个需要执行相同操作的客户端来解决维护问题。使用该服务的客户数量越多,维护收益就越大。
菲尔·帕特森

1
还有安全性-服务层可以为黑客提供另一堵墙,以破坏数据库中的财富。缺乏服务层也许就是为什么如此多的网站遭到巨大破坏,而中间存在一项服务的原因,因此,黑客在被检测到之前将获得少得多的数据。
gbjbaanb

6

我见过的大多数服务层都是一团糟。服务往往有很多不同的方法,1500 LOC并不罕见。不同的方法没有共同点,但是共享代码。这导致高耦合,低内聚。它也违反了OCP,因为每次需要新操作时,您都必须修改代码而不是扩展代码库。从理论上讲,构造良好的服务层是可能的,但我在实践中从未见过。

CQRS解决了这些问题,使您不必创建这些过程服务层之一。


2
用谁的标准构造得好?当然,按照OO标准,服务层接口是一团糟。从功能或过程的角度来看,它鼓励采用美观的分层设计方法。我认为服务层最大的困扰是他们鼓励基于无状态事务的应用程序,并且不鼓励使用纯面向对象的方法。我可以理解论点的两面。
maple_shaft

6

添加接口(服务层是接口的一种)需要花费时间。一个好的人需要花费很多时间进行设计和测试。第一次尝试正确使用它非常重要,因为稍后进行更改会破坏所有客户端。另外,请考虑,直到您有另一个需求稍有不同的客户端,您才可能不知道该界面中需要什么。维护服务本身就是一个永无止境的项目。

在大多数组织中,如果您去找企业赞助商并问他们:“您是否希望其他部门从我们的预算中开发(重用)我们正在开发的系统中受益?” 他们会嘲笑你的。首先让它为您的业务发起人工作,然后再开始重新使用该代码(在部门自己的时间)。

如果您知道,事实上,您今天编写的功能将被多个不同的服务客户端重用,那么请考虑从第一天开始设计服务层。如果不确定,或者项目中已经有许多未知数,请先进行一些简单的工作,然后在有时间和预算的情况下将其分为服务和客户端。从工作系统开始,在第一次尝试时正确设置服务接口要容易得多。

PS:如果您使用Java,那么Joshua Bloch在他的《 Effective Java》一书中都有许多很棒的界面建议。


没有无菌理论的好答案。
danilo

2

我同意你的看法。如果您使用的是单个UI,则无需再包含一层。

DAL,BL和UI / Controller是设计应用程序的良好组合。如果您打算使用单个UI,则无需准备额外的层。在应用程序中增加1层只会增加开发工作量/时间。

另一个简化方案是在应用程序中使用多个UI,在这种情况下,最好有一个服务层来处理UI。

堆栈溢出:关于服务层模式的讨论


那么,您是否建议在每个复杂的应用程序开发人员中,他都应该使用服务层,而不仅仅是DAL,BL,UI层?
BornToCode 2012年

如果有多个UI,我们必须包含一个服务层。在您的情况下,我认为没有必要准备新的图层。这只会增加应用程序的复杂性。
Satish Pandey,2012年

0

我会争辩您的BL是您的服务层。业务逻辑所在的中心位置。这应该是一个DLL,可以由需要该逻辑的任何人使用。然后,如果您的应用程序具有不同的UI,则可以在其上放置一个Web api层。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.