サービス層を作成することはどれほど重要ですか?


68

3層(DAL、BL、UI)でアプリの構築を開始しました[主にCRM、いくつかの販売レポート、在庫を処理します]。

同僚から、サービスレイヤーパターンに移行する必要があり、開発者が経験からサービスパターンにアクセスするようになったと言われました。彼は、将来そのようにアプリケーションを維持する方がはるかに簡単になるだろうと言いました。

個人的に、私はそれが物事をより複雑にしているだけだと感じており、それを正当化するような利益はあまり見られませんでした。

このアプリには、デスクトップアプリケーションの機能の一部(ただしごくわずか)を使用する小さな部分UIが追加されているため、コードを(あまり多くは)複製していません。いくつかのコードの重複のために、私はそれをサービス指向に変換しませんが、一般的にそれは非常に優れたアーキテクチャであるため、とにかくそれを使用するべきだと言いました。

私はそれでグーグルしようとしましたが、私はまだ混乱しており、何をすべきかを決めることができません。

回答:


58

マーティンファウラーの著書「Patterns of Enterprise Architecture」は次のように述べています。

答えが簡単な質問は、おそらくそれを使用しない場合です。アプリケーションのビジネスロジックが1種類のクライアント(たとえば、ユーザーインターフェイス)のみを持ち、ユースケースの応答に複数のトランザクションリソースが含まれない場合、おそらくサービスレイヤーは必要ありません。[...]

しかし、2番目の種類のクライアント、またはユースケースの応答で2番目のトランザクションリソースを想定するとすぐに、最初からサービスレイヤーでの設計に費用がかかります。

サービス層が提供する利点は、さまざまなクライアントが利用できるアプリケーション操作の共通セットを定義し、各操作で応答を調整することです。ビジネスロジックを消費する複数の種類のクライアントがあり、複数のトランザクションリソースが関係する複雑なユースケースを持つアプリケーションがある場合、マネージドトランザクションにサービスレイヤーを含めることは理にかなっています。

CRM、セールス、インベントリには、CRUDタイプのユースケースが多数あり、そのほとんどの場合、サービスレイヤーのオペレーションと1対1の対応があります。ドメインオブジェクトの作成、更新、または削除に対する応答は、サービスレイヤーの操作によって原子的に調整および処理される必要があります。

サービスレイヤーを持つことのもう1つの利点は、ローカルまたはリモートの呼び出し、またはその両方のために設計できることです。また、そのための柔軟性を提供します。このパターンは、アプリケーションのビジネスロジックのカプセル化された実装と、さまざまなクライアントによる一貫した方法でのそのロジックの呼び出しの基盤となります。これは、クライアントが同じ共通サービスを共有するため、コードの重複も削減/削除することを意味します。ビジネスロジックが変更された場合、(通常)サービスを変更するだけで、各クライアントではなく、メンテナンスコストを削減できる可能性があります。

要約すると、サービスレイヤーを使用するのは良いことです。さらに、ビジネスロジックの複数のクライアントがあるように聞こえるので、あなたの例で提供したと思います。


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

4
そのような場合、それを利用できるクライアントが1つだけになることはまれです。UIが1つしかない場合、セキュリティと再利用性という2つの理由が考えられます。一般的なエンタープライズセットアップでは、外部クライアントがUIアプリを使用でき、サービスレイヤーはネットワークでのみ使用できます。そのため、Webサーバーは、ネットワークのロックダウンされた部分に作業を遅延させます。セールスの例では、Webサイトからセールスを取得してeBayまたはAmazonに展開すると、再利用できます。これで、1つのUIと複数のクライアントができました。
フィルパターソン

5
@PhilPattersonからのコメントに追加するだけです。複数のクライアントがUIベースである必要はありません。Webサービスまたはライブラリを考えてください-それらはクライアントにもなり得ます。フロントエンドUIは、サービスレイヤーとパッケージ化したソフトウェアサービスを使用し、他の人に使用を許可する場合があります。
デコ

サービス層の例を提供できますか?
user962206

34

あなたのアイデアを評価し、その最善のアプローチを締結しているため、サービスレイヤの追加:良いです

:それはすべてのクールな子供たちがやっていることだからサービス層を追加する悪いです

あなたの腸があなたがそれを必要としないと言ったら、それを作らないでください。

過去10年ほどでプログラミングの世界で最も残念な開発の1つは、人々が今シーズンの靴のようにトレンドや時流に追随するという、いらいらする「ファッション」指向になったことです。そのtrapに陥らないでください。来シーズン、「誰もが」あなたがそれを他の方法で設計すべきだったとあなたに告げるからです。

サービス層には何の問題も正しいものもありません。それは、手元のプロジェクトの技術的メリットでその適合性を評価する必要がある特定のアプローチです。自分の判断を他の人の意見に置き換えることを余儀なくされてはいけません。


27
これは主題をまったく扱っておらず、ほんの数語を置き換えた後、このサイトのほぼすべての質問に適用できる開発プラクティスについての包括的な声明/暴言を作成するだけです。この回答を読んでも、サービス層何であるかを正確に知っているとは確信していません。
アーロンノート

12
それは確かに他の質問に適用することができます...それは真実ではありません。彼のプロジェクトで必要なものを述べるために必要なコンテキストの近くにあなたも私もいないという事実はありません。OPがここで必要とするのは、正しいと判断した意思決定を行うための少しの精神的サポートです。
GrandmasterB

5
@Aaronaught答えの正しさに関係なく、彼は基本的に「サービス層はどれほど重要ですか?」という主要な質問に本質的に答えています。彼はまったく本質的ではないと主張し、それはおそらく単なる流行だと主張している。答えに同意できない場合は、投票してください。
maple_shaft

2
@GrandmasterB私は、ファッションはソフトウェア開発に適していると主張します。ほとんどの開発者は、十分な情報に基づいた設計およびアーキテクチャの決定を下すには、新鮮すぎるか無能です。それでも私たちは彼らが働くソフトウェアのように見えることを期待していますので、彼らが時流に乗って、貧弱な設計選択と一貫していることは、何年も前に行われた方法よりもはるかに好まれており、保守性があります理解も感謝もしませんでした。
maple_shaft

10
@maple_shaft明確にするために、サービスレイヤーが流行しているとは言いません。私は、質問の質問に基づいて、彼の同僚が彼のプロジェクトで保証されているとは思わないアーキテクチャを使用するように促すために、彼の同僚の側にファディッシュ/ファッション/バンドワゴンの行動があるようだと言っています。私は答えでそれを明確にします。サービスレイヤー(または他の概念)は、それだけであると考えています-中立的な概念で、個々のプロジェクトの適性を評価する必要があります。自分の判断で必要でないと判断された場合は、適用/使用しないでください。
GrandmasterB

22

サービスレイヤーの作成を決定する要因は多数あります。次の理由で、過去にサービスレイヤーを作成しました。

  1. 複数のクライアントが再利用する必要があるコード。
  2. ライセンスが制限されているサードパーティのライブラリ。
  3. システムへの統合ポイントを必要とするサードパーティ。
  4. 複製されたビジネスロジックを集中化します。

ケース1:無数のさまざまなクライアントが使用する必要がある基本機能を作成しています。サービスレイヤーは、さまざまなクライアントがすぐに提供された機能を利用できる機能を組み込みます。

ケース2:通常、アプリスペースでコードをホストしていますが、ライセンスが制限されているサードパーティのライブラリを使用しています。この場合、どこでも使用したいリソースがありますが、限られた数だけです。サービスの背後でホストする場合、組織全体が各ホスティングのライセンスを購入することなく、アプリケーションから使用できるようになります。

ケース3:サードパーティが通信するための機能を構築しています。この例では、在庫エンドポイントを設定して、ベンダーが製品の入荷に関するメッセージを渡すことができるようにすることができます。

ケース4:エンタープライズ全体でコードを分析し、別々のチームが同じものを作成していることがわかりました(わずかに異なる方法で実装されただけです)。サービスレイヤーを使用すると、最適なアプローチを選択できます。また、サービスを呼び出すことで、すべてのチームに同じプロセスを実装できます。ロジックを集中化するもう1つの利点は、バグが見つかったときです。これで、修正プログラムを1回展開するだけで、すべてのクライアントが同時にメリットを享受できます。

これはすべて、サービスレイヤーにマイナスの可能性があると言われています。

  1. システムの複雑さが増します。以前はデバッグするアプリケーションが1つだけだったのに、2つありました。運用上の問題には、クライアントアプリの設定、サービスアプリの設定、またはクライアントアプリとサーバーアプリが正しくセットアップされていない場合の通信の問題を確認する必要があります。これまで経験したことがない場合、これは注意が必要です。
  2. 障害の一点。サービスが停止すると、すべてのクライアントが影響を受けます。この方法でコードが展開されていない場合、リスクは低くなります(ただし、これを軽減する方法はあります)。
  3. バージョニングを行うのは難しい場合があります。インターフェースを展開するサービスを使用する1つのアプリがある場合、2つの間で同時に変更を行うことができます。複数のクライアントがある場合は、V1のユーザーを管理し、V2のユーザーを管理し、V1の削除を調整する必要があります(すべてのユーザーがV2に更新したことがわかったら)。

主なポイントは、システムをサービス指向にすることは必ずしもスラムダンクではないということです。私の経験では、通常は良いアイデアです(この方法でアプリケーションを構築する傾向があります)が、それは自動的な決定ではありません。結局のところ、長所と短所を比較検討し、あなたの状況に合った決定を下す必要があります。


2
+1有益な答えをありがとう。私は本当にあなたの答えやデコの答えを受け入れる天気に疑問を持っていました。最終的に私はあまり経験がないので、私はほとんどの賛成票を得る答えを選ぶことにしました。私はまだあなたの答えがより多くの賛成に値すると思う。いずれにしても、あなたがあなたの知識と経験を共有してくれたことに本当に感謝しています。ありがとうございました!
BornToCode

1
どういたしまして!両方の答えを取り除く主なポイントは、これは(主に)同じことをする必要がある複数のクライアントを持つことで、メンテナンスの問題を解決することに関することです。サービスを使用するクライアントの数が多いほど、メンテナンスの利益は大きくなります。
フィルパターソン

1
また、セキュリティもあります。サービスレイヤーは、ハッカーがDB内の宝物に到達するために侵害する別の壁を提供できます。サービスレイヤーの欠如が、おそらく非常に多くのWebサイトが大きな侵害を受けている理由であり、サービスが中央にあるため、ハッカーは検出される前にデータが大幅に少なくなります。
gbjbaanb

6

私が見たほとんどのサービス層は完全な混乱です。サービスには多くの異なる方法がある傾向があり、1500 LOCは珍しいことではありません。異なるメソッドには共通点はありませんが、コードを共有します。これにより、結合度が高く、凝集度が低くなります。また、OCPに違反します。新しい操作が必要になるたびに、コードベースを拡張する代わりにコードを変更する必要があるためです。よく構築されたサービス層は理論的には可能ですが、実際には見たことがありません。

CQRSはこれらの問題を解決し、これらの手続き型サービスレイヤーの1つを作成する必要がないようにします。


2
しかし、誰の基準でうまく構築されていますか?確かにオブジェクト指向の標準では、サービス層インターフェースは混乱の完全な難破船です。機能的または手続き的な観点からは、美しい階層化された設計アプローチを促進します。人々がサービス層で抱えている最大の問題は、ステートレスなトランザクションベースのアプリケーションを奨励し、純粋なオブジェクト指向のアプローチを思いとどまらせることだと思います。私は議論の両側を理解することができます。
maple_shaft

6

インターフェイス(サービスレイヤーはインターフェイスの一種です)の追加には時間がかかります。良いものは、設計とテストに時間がかかります。後で変更するとすべてのクライアントが破損するため、最初の試行で正しく設定することが非常に重要です。また、わずかに異なるニーズを持つ2番目のクライアントが見つかるまで、そのインターフェイスに何が必要かはおそらくわからないと考えてください。サービスの維持は、それ自体で終わりのないプロジェクトです。

ほとんどの組織では、ビジネススポンサーに行って、「他の部門に予算で開発しているこのシステムのメリットを(再利用)してもらいたいですか?」彼らはあなたを笑います。最初にビジネススポンサーのために機能させてから、そのコードを(部署の都合に合わせて)再利用してみてください。

実際、今日書いている機能が複数の異なるサービスクライアントによって再利用されることがわかっている場合は、初日からサービスレイヤーの設計を検討してください。不明な場合、またはプロジェクトに多くの未知のものが既にある場合は、最初に単純な作業を行い、時間と予算があれば後でサービスとクライアントに分けます。稼働中のシステムで開始する場合、最初の試行でサービスインターフェイスを取得する方がはるかに簡単です。

PS Javaで作業している場合、Joshua Blochの著書「Effective Java」では、素晴らしいインターフェースのアドバイスがたくさんあります。


無菌理論のない素晴らしい答え。
19:46のdanilo

2

仰るとおりです。単一のUIを使用している場合、もう1つのレイヤーを含める必要はありません。

DAL、BL、およびUI / Controllerは、アプリケーションの設計に適した組み合わせです。単一のUIを使用する場合、追加のレイヤーを準備する必要はありません。アプリケーションにさらに1つのレイヤーを含めると、開発の労力/時間が増加するだけです。

もう1つの方法は、アプリケーションで複数のUIを使用することです。この場合、UIを処理するサービスレイヤーを用意することをお勧めします。

スタックオーバーフロー:サービスレイヤーパターンに関する議論


複雑なアプリケーションを開発するたびに、DAL、BL、UIレイヤーだけでなく、サービスレイヤーを使用することをお勧めしますか?
BornToCode

複数のUIの場合、サービスレイヤーを含める必要があります。あなたの場合、新しいレイヤーを準備する必要はないと思います。アプリケーションの複雑さが増すだけです。
サティッシュパンディ

0

私はあなたのBLがあなたのサービス層であることを争います。ビジネスロジックが配置される中心的な場所。これは、そのロジックを必要とするあらゆるものが使用できるDLLでなければなりません。その後、アプリのUIが異なる場合は、その上にWeb APIレイヤーを配置できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.