データ層間通信のためのDTO設計
DTO(Data Transfer Object)は、Controller層とService層の間でデータをやり取りするための中立的な構造です。典型的な使用例として、HTTPリクエストで受け取ったデータをビジネスロジック層に渡す際のラッパーとして機能します。
UI専用のVO構造
VO(View Object)は、UI層に特化したデータ表現形式です。特定の画面やコンポーネントに表示するためのデータを一括して保持し、画面設計に応じた柔軟なフィールド構成が可能です。
DTOとVOの設計上の違い
- 役割の違い:DTOは層間通信を目的とし、VOはUI表示を目的とする
- 変更性の違い:DTOは可変状態を許容、VOは原則としてイミュータブル
- ロジックの有無:DTOはデータ転送専用、VOはフォーマット変換ロジックを含む場合がある
Spring Bootでの実装例
// リクエストデータの受信用構造体
public class UserInfoTransfer {
private String username;
private Integer yearsOld;
// プロパティアクセサーは省略
}
// レスポンスデータの構造体
public class UserDisplay {
private String displayName;
private Integer age;
private LocalDateTime registrationDate;
// ゲッター・セッターは省略
}
Controller層の実装
@RestController
public class UserController {
@Autowired
private UserService service;
@PostMapping("/register")
public ResponseEntity<UserDisplay> registerUser(@RequestBody UserInfoTransfer input) {
UserDisplay result = service.processRegistration(input);
return ResponseEntity.ok(result);
}
}
Service層の実装
@Service
public class UserService {
@Autowired
private UserRepository repository;
public UserDisplay processRegistration(UserInfoTransfer input) {
// ビジネスロジック実行
UserEntity entity = new UserEntity();
entity.setName(input.getUsername());
entity.setAge(input.getYearsOld());
repository.save(entity);
// 表示用オブジェクトの構築
UserDisplay response = new UserDisplay();
response.setDisplayName(entity.getName());
response.setAge(entity.getAge());
response.setRegistrationDate(LocalDateTime.now());
return response;
}
}
この設計により、Controller層とService層の疎結合が実現されます。DTOはデータの受け皿として、VOはプレゼンテーション層のニーズに応じたデータ構造として、それぞれ明確な役割を果たします。