※当サイトの記事には、広告・プロモーションが含まれます。

Serviceクラスの粒度ってどのぐらいが良いのか

nazology.net

amazing...

Serviceクラスって?

stackoverflowによると、

stackoverflow.com

There is no hard definition for what you're asking about, only 'general practices' that people adhere to more or less, depending on the circumstance.

https://stackoverflow.com/questions/34619221/a-few-questions-about-service-classes

⇧ 厳密な定義はないとのこと。

ただ、

Ideally, you would create a "service" class that handles all business logic for a group of operations. The benefit is you now have a place to call other classes (DAO's including other service classes) and have them interact with each other. Chances are you would refactor anyway to using "service" classes as your app grows and becomes harder to refactor without breaking other classes.

https://stackoverflow.com/questions/34619221/a-few-questions-about-service-classes

⇧ 操作毎にビジネスロジックを包括したServiceクラスを作っておけば、別のServiceクラスを呼び出したりできるメリットがあるそうな。

ちなみに、Serviceクラスから別のServiceクラスを呼び出すのは、

stackoverflow.com

softwareengineering.stackexchange.com

⇧ 御法度というわけではないらしい。

上記でマーティン・ファウラー氏の「AnemicDomainModel(ドメインモデル貧血症)」の話が出てきて、

martinfowler.com

Eric Evans's excellent book Domain Driven Design has the following to say about these layers.

Application Layer [his name for Service Layer]: Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program.

Domain Layer (or Model Layer): Responsible for representing concepts of the business, information about the business situation, and business rules. State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure. This layer is the heart of business software.

The key point here is that the Service Layer is thin - all the key logic lies in the domain layer. He reiterates this point in his service pattern:

Now, the more common mistake is to give up too easily on fitting the behavior into an appropriate object, gradually slipping toward procedural programming.

https://martinfowler.com/bliki/AnemicDomainModel.html

⇧ その中でエリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」の話に触れていて、Service Layerには役割を持たせ過ぎてはいけないってことを仰ってますと。

エリック・エヴァンス氏は、『Application Layer [his name for Service Layer]』って発言してることから、Application Layer = Service Layerって考えてるってことなんかな?

エリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」の書籍のlayered architectureの図を紹介してくれてるサイトがあり、確認してみると、

qiita.com

⇧ 確かに、レイヤーとしては、サービスという名前は出てこない、Service Layerって名前を出すんなら、図にも反映して欲しいですな、エリック・エヴァンス氏...

このあたり、Service Layerの階層がハッキリしないせいか、

qiita.com

www.w2solution.co.jp

⇧ 結構、人によってServiceの解釈がまちまちだったりする。

Spring Frameworkとか使ってると、

www.infoq.com

⇧ 上図のような構成が構成が多くなるような気もする。こうして見ると、Application LayerとDomain Layerの狭間にいるように思うのだけど、Service Layerってものがいよいよハッキリしない...

エリック・エヴァンス氏は、『Application Layer [his name for Service Layer]』と『This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down.』と発言してることからApplication Layer寄りでService Layerを考えているのだとは思うのだけど、Spring Frameworkにおいては、Service LayerがDomain Layer寄りになるような仕様になっている気がする。

エリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」で考えているService LayerとSpring Frameworkの考えているService Layerは定義が異なっているように思われるから、Service Layerの定義を統一して欲しかった感はありますね、もう手遅れっぽいけど。

と思ったら、

spring.pleiades.io

アノテーション付きクラスが「サービス」であり、ドメイン駆動設計(Evans、2003)によって「カプセル化された状態でモデル内に単独で存在するインターフェースとして提供される操作」として最初に定義されたことを示します。

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Service.html

⇧ なるほど、Spring Frameworkとしては、エリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」をなぞらえているということらしいのだけど、Spring Frameworkの「サービス」がエリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」のどのLayerに属するものなのかがサッパリ分からん...

APIドキュメントの説明で、『カプセル化された状態でモデル内に単独で存在するインターフェースとして提供される操作」』とモデルとか出てくるってことは、Spring Frameworkの「サービス」は、エリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」で言うところのDomain Layerに属するという話で良いんだろうか?

う~む、結局、エリック・エヴァンス氏の『Application Layer [his name for Service Layer]』って言葉がややこしくしてる気がする...

Serviceクラスの粒度ってどのぐらいが良いのか

stackoverflowの話に戻ると、

softwareengineering.stackexchange.com

You are facing a problem of an anemic domain model which leads to uncertainty about where to put "general" business logic which is unspecific to a usecase.

https://stackoverflow.com/questions/34619221/a-few-questions-about-service-classes

There are two types of business logic:

  1. usecase specific
  2. usecase unspecific

https://stackoverflow.com/questions/34619221/a-few-questions-about-service-classes

ビジネスロジックは、大きく分けて、

の2つに分けられるってことで、ユースケースに固有かそうでないかによってServiceクラスを分割しても良いってことなんかね?

ユースケースと言うと、

ユースケース図とかが有名ではあるけど。

で、ユースケースにも粒度はあって、

xtech.nikkei.com

 アジャイル開発プロセスで著名なアリスター・コバーン氏は,図2に示したように,ユースケースの3つの粒度のレベルを定義している。1つは,業務全体を指す「要約レベル」,2つ目が1人の担当者が行う1回の作業を指す「ユーザー目的レベル」,3つ目がシステム面から見た機能を表す「サブ機能レベル」――である。

反復型開発における見積もりの実際 | 日経クロステック(xTECH)

⇧ 3つの粒度に分けられるそうな。

う~む、Serviceクラスの粒度としては、業務全体を表わすユースケースの粒度(上図で言うところの「要約レベル」)に合わせれば良いのだろうか...

ただ、そうなると、Serviceクラスが肥大化するケースが出てくると思われて、エリック・エヴァンス氏の「Domain Driven Design(ドメイン駆動設計)」で言ってるかどうかは分からんのだけど、

『Application Layer [his name for Service Layer]: Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin.

って言葉を満たすことができなくなりますな、まぁ、エリック・エヴァンス氏の言うService Layerでの役割が、我々の考えるServiceクラスの役割と噛み合っていない気がするので何とも言えないですが...

個人的には、

The domain layer:

  • contains service objects that only have a defined operational behavior which is not part of any domain object. Services encapsulate behavior of the business domain that doesn't fit in the domain objects themselves.

https://www.infoq.com/articles/ddd-in-practice/

⇧ 上記のような役割をServiceクラスが担っているで良いような気はするんだけど。

結局、Serviceクラスの粒度の正解が分からんではないか...

まぁ、開発してるシステムにも依りけりだとは思うのだけど、一般的に標準と思しきServiceクラスの粒度ってのを知りたいところですな。

ちなみに、

The term was coined by Eric Evans in his book of the same title published in 2003.

https://en.wikipedia.org/wiki/Domain-driven_design

⇧「Domain Driven Design(ドメイン駆動設計)」という用語は、エリック・エヴァンス氏の書籍が発祥らしいですが、「Domain Driven Design(ドメイン駆動設計)」的な考え方の発祥は謎です。

ソフトウェアの起源としては、

The very first time a stored-program computer held a piece of software in electronic memory and executed it successfully, was 11 am 21 June 1948, at the University of Manchester, on the Manchester Baby computer. It was written by Tom Kilburn, and calculated the highest factor of the integer 2^18 = 262,144. Starting with a large trial divisor, it performed division of 262,144 by repeated subtraction then checked if the remainder was zero. If not, it decremented the trial divisor by one and repeated the process. Google released a tribute to the Manchester Baby, celebrating it as the "birth of software".

https://en.wikipedia.org/wiki/History_of_software

⇧ 1948年らしく、アプリケーション開発が発展していく過程で「Domain Driven Design(ドメイン駆動設計)」的な考え方の需要が生まれたと思うので、「Domain Driven Design(ドメイン駆動設計)」的な考え方の発祥は、少なくとも1948年以降ってことになるんではないかと。

毎度モヤモヤ感が半端ない...

今回はこのへんで。