3層アーキテクチャとは?メリットとSpring Framework での実装例
このレクチャーでは、規模の大きい Web アプリケーション開発で役に立つ3層アーキテクチャについて紹介します。 規模が大きい開発ではソースコードの量が膨大になります。 そのため、コードを整理するための戦略が必要です。 3層アーキテクチャはソースコードを3つの役割で分類し整理する方法です。
このレクチャーでは、3層アーキテクチャについて理解を深め、Spring Framework での実装例を見ていきます。
目次
3層アーキテクチャとは?
まずは、Spring Framework に依らない一般的な3層アーキテクチャを理解しましょう。 3層アーキテクチャの「3層」とは
- プレゼンテーション層
- ビジネスロジック層
- データアクセス層
の3つのことです。3層アーキテクチャでは、システム全体をこれらの3つの層に分けて設計・実装する方法です。 それでは、それぞれの層の役割についてさらに深く理解しましょう。
プレゼンテーション層
UI(ユーザーインターフェース)層と呼ばれることもあります。 この層はユーザーと直接対話する部分です。ウェブページやユーザーインターフェースの要素を含んでいます。
ビジネスロジック層
ドメイン層またはサービス層とも呼ばれます。 この層はアプリケーションの主要な処理やビジネスルールを担当します。 プレゼンテーション層からのリクエストを受け取り、適切な処理を行ったあと、結果をプレゼンテーション層に返します。
Web アプリケーションのそもそもの存在意義は、「現実世界で役に立つか」「競合他社と差別化できるか」などビジネス的な観点で説明されます。 その点から考えて、ビジネスロジック層はWebアプリケーションの競争力の源泉となり、最も重要な部分となります。
データアクセス層
永続化層とも呼ばれます。 この層はデータベースや外部サービスとのやりとりを担当します。 データの永続化(保存)や取得、更新、削除などの操作がこの層で行われます。 SQLなどのデータベースへの操作を抽象化することで、ビジネスロジック層がデータベースの詳細を知る必要がなくなり、システムの拡張性や交換性が向上します。
3層アーキテクチャのメリット
3層アーキテクチャには、以下のようなメリットがあります:
- 結合度の低減:各層は独立して動作するため、変更の影響が他の層に及ばない
- 凝集度の向上:関連する機能やロジックが同じ層にまとめられるため、可読性や保守性が向上する
これにより、大規模開発やチーム開発の際の効率が大幅に向上します。
Spring Framework での 3層アーキテクチャコード例
Spring Frameworkでの3層アーキテクチャ実装の典型的なコードを示します。
プレゼンテーション層
Spring MVC を使用すると、コントローラを介してユーザーのリクエストを受け取り、適切なビューを返すことができます。
@Controller
アノテーションを持つクラスは、ユーザーのリクエストを処理するためのエンドポイントとして機能します。
ビュー技術としては、JSP, Thymeleaf, FreeMarker などが利用できます。
以下の TaskController
では、POST /tasks
の HTTP リクエストを処理する create
メソッドが定義されています。
createTask
メソッド内で、ビジネスロジック層の TaskService#create
を呼び出しています。
@Controller
public class TaskController {
private final TaskService taskService;
@PostMapping("/tasks")
public String create(TaskForm form) {
TaskEntity newEntity = form.toEntity();
taskService.create(newEntity);
return "redirect:/tasks";
}
}
ビジネスロジック層
Spring には、トランザクション管理や依存性の注入(DI)などの機能が豊富に提供されているため、ビジネスロジックの実装が容易になります。
通常、サービスクラスは、@Service
アノテーションをつけます。
また、トランザクションを制御するための @Transactional
アノテーションを使用することが多いです。
この層では、データアクセス層で取得したデータの変換やビジネスルールの適用などの処理を行います。
以下の例では、ビジネスロジック層のメソッドである TaskService
クラスの create
メソッドが定義されています。
このメソッドはプレゼンテーション層の TaskController#create
メソッドから呼び出され、処理の中でデータアクセス層の TaskRespository#insert
を呼び出します。
create
メソッドがトランザクション境界になるように @Transactional
アノテーションが付与されています。
@Service
public class TaskService {
private TaskRepository taskRepository;
@Transactional
public void create(TaskEntity newEntity) {
taskRepository.insert(newEntity);
}
}
データアクセス層 (MyBatisの場合)
Spring Data JPA, Spring JDBC などのモジュールを使用して、データベースとのやりとりを抽象化・効率化できます。
この層のクラスは、通常 @Repository
アノテーションを持ちます。
MyBatis を利用する場合は @Mapper
アノテーションを付けます。
以下の TaskRepository
クラスには、タスクのレコードをデータベースに登録する insert
メソッドが定義されています。
このメソッドはビジネスロジック層の TaskService#create
メソッドから呼び出されます。
@Mapper
public interface TaskRepository {
@Insert("""
INSERT INTO tasks (
summary
, description
, status
) VALUES (
#{task.summary}
, #{task.description}
, #{task.status}
)
""")
void insert(@Param("task") TaskEntity newEntity);
}
まとめ:大規模な Web アプリケーション開発にはコードを整理する戦略が必須
3層アーキテクチャは、ソフトウェア設計の基本的なパターンの一つです。 規模が大きいソフトウェア開発では、このような設計パターンを適用しソースコードの管理をすることが必要です。 3層アーキテクチャの考えを Spring Framework での開発と組み合わせることで、効率的なアプリケーションの開発が可能です。