0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Javaのカプセル化とMVC設計:なぜ「public」だらけになるのか?

Javaを学ぶ過程で「カプセル化(隠蔽)」という概念に出会いますが、実際にMVCなどのレイヤードアーキテクチャで開発を始めると、理想と現実のギャップに直面し、

「あれ? カプセル化って隠すことだよね? なのにMVCで作るとほとんどのクラスをpublicにしないと動かない…これって設計として正解なの?」

という疑問から、パッケージの範囲とアクセス修飾子という観点、「MVC設計のジレンマ」について記事としてまとめました。

PS.なぜ今頃カプセル化について疑問に思ったかというと、ミノ駆動さんの改訂新版 良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方を読んでおり、あれ???となったことがきっかけです。良書なので、ジュニアからミドルになる層は読んだほうがいいと思います。

カプセル化とアクセス修飾子の基本ルール

Javaにおけるカプセル化は、アクセス修飾子を使って「どこから見えるか」を制限することで実現されます。まずは改めて整理しましょう。

ここで注目すべきは、「何も書かない(パッケージプライベート)」という選択肢です。これは「同じパッケージ(フォルダ)内のクラス同士なら自由にアクセスできるが、外からは隠す」という、Javaが提供する強力な隠蔽機能です。

そもそもパッケージの「範囲」と物理的な境界って?

Javaの「パッケージ」は、ドメインやプロジェクト全体ではなく、「同じソースフォルダ(ディレクトリ)構造を共有している範囲」を指します。

  • 同じパッケージ: 物理的に同じフォルダにあるクラス同士。修飾子なしでアクセス可能。
  • 別のパッケージ: 物理的に違うフォルダにあるクラス同士。public がないと一切アクセス不可能。

つまり、MVC構成のように com.app.controllercom.app.serviceパッケージを分けた時点で、それらの間には「物理的な壁」が作られることになります。

では、なぜMVCだと「public」だらけになるのか?

MVCでは役割ごとにパッケージを分けるため、必然的に別のパッケージ間でのクラス利用が発生します。

  • ControllerService を呼び出す。
  • ServiceRepository を呼び出す。

これらは全て「別のパッケージ」に属しているため、ControllerがServiceを呼ぶためには、Service側で public を宣言しなければなりません。結果、本来は「Service内部で閉じたい処理」まで、プロジェクト全体から呼べる public メソッドになってしまうのです。

「publicだらけ問題」とどう向き合うか?

このジレンマに対して、実務では以下の3つのステップで対処します。

ステップ1:「publicは契約である」と割り切る

すべてを隠すのがカプセル化ではありません。public は「このクラスの機能として外部(他のレイヤー)に提供するAPI」という契約だと考えます。Controllerから呼ばれるメソッドは public で正解です。しかし、Service内部でしか使わない補助的なメソッドは、きちんと private にする。この意識を持つだけで、カプセル化は十分機能します。

ステップ2:インターフェースによる隠蔽

Serviceの実装詳細を徹底的に隠したい場合は、インターフェースを導入します。

  1. UserService(インターフェース)を public にする。
  2. UserServiceImpl(実装クラス)を 修飾子なし(パッケージプライベート) にする。

これによって、Controllerはインターフェースしか見えないため、実装クラス内の詳細なコードに触れることは物理的にできなくなります。

ステップ3:モジュールシステム(Java 9+)

より厳格に管理したい場合は、module-info.java を使います。公開したくないパッケージを「エクスポート」しない設定にすることで、public クラスであっても外部からアクセスさせないという、強固な防御が可能になります。

まとめ:カプセル化の目的を見失わない

MVC設計において「publicが増えること」は、必ずしも設計の失敗ではありません。むしろ、「どこを公開して、どこを隠すかという設計意図(API設計)を明確にするチャンスです。

  • 小規模: インターフェースとアクセス修飾子の使い分けで十分。
  • 大規模: モジュールシステムまで活用し、依存関係を厳格化する。

カプセル化」という言葉に縛られすぎず、「どの範囲まで見せれば、プログラムの結合度が適切に保てるか?」という視点を持つことが、MVCを使いこなす第一歩です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?