CodeIgniter初心者の方に知って欲しいCodeIgniterでのMVCについて
MVCとは?
『CodeIgniter徹底入門』によると?
『CodeIgniter徹底入門』(P.76)によると、コントローラ、モデル、ビューは以下のように説明されています。
- Controller(コントローラ)は、入力データに従って適切なデータを呼び出したり、ModelやViewの連携など、アプリケーション全体の制御を行なう
- Model(モデル)は、データベースへのアクセスやデータの修正/加工などの処理を行なう
- View(ビュー)は、処理結果の表示など、画面表示を担当する
なんとなくわかったようなわからないような説明です。
実際には書籍にはもっといろいろな説明があるので読めば理解が進むと思いますが、コントローラとモデルの区別は実はそんなに簡単ではありません。
CodeIgniter User Guideによると?
公式ドキュメントではどのように説明されているでしょうか。
- The Model represents your data structures. Typically your model classes will contain functions that help you retrieve, insert, and update information in your database.
- The View is the information that is being presented to a user. A View will normally be a web page, but in CodeIgniter, a view can also be a page fragment like a header or footer. It can also be an RSS page, or any other type of “page”.
- The Controller serves as an intermediary between the Model, the View, and any other resources needed to process the HTTP request and generate a web page.
モデルはデータの構造を表し、典型的にはデータベースの情報を処理する。
ビューはユーザに表示される情報で、通常はWebページまたはヘッダやフッタなどのページの断片。
コントローラはモデルとビューやその他のリソースの仲介者。
やはり、コントローラとモデルの区別はそんなに簡単ではありません。
何故CodeIgniterはMVC初心者に使いやすいのか?
CodeIgniterではURIに関連付けられたクラス(コントローラ)が実行されます。そのコントローラさえあれば、その中のメソッドが実行されて結果としてページが出力されます。
CodeIgniterではモデルはオプションとされており、従わないとコードが動作しないフレームワークの規約もほとんどありません。例えば、コントローラとモデルやビューファイルが規約により紐づいており、自動的に実行されるようなことは一切ありません。
なので、MVCでない既存のコードがあれば、それをコントローラに移せばだいたい動作します。つまづくことが少ないのです。
そして、HTMLをビューに分離し、データベース関連のロジックをモデルに分離すると、MVC以前のコードより見通しがよくなります。
ただし、ここでめでたしめでたしとはなりません。
何が問題か?
ファットコントローラになりやすいことです。
ファットコントローラとは長すぎるコントローラのことでアンチパターンです。何行だとファットかという基準があるわけではないですが、100行を大きく超えるようなコントローラはファットコントローラでしょう。
例えば、モデルをデータベースアクセスに限定してしまうと、残りのロジックはコントローラに記述されることになり、必然的にコントローラが長くなります。
どうすれば?
コントローラを薄くすることです。
そもそもMVCでもっとも重要なパーツはモデルです。いわゆるビジネスロジックやドメインモデルと言われるコードはモデルに記述します。
CodeIgniterでは、MVC以外に「ライブラリ」と「ヘルパー」が存在します。ここで、ヘルパーは関数を定義するものです。クラスを定義するには、ライブラリを使います。
つまり、CodeIgniterではビジネスロジックやドメインモデルを
application/models
フォルダに配置するapplication/libraries
フォルダに配置する
という方法が考えられます。
ライブラリについては、CodeIgniterの標準のライブラリなどから、プロジェクトを超えて共有されるべきものというイメージを持つ人がいるかも知れませんが、それにとらわれる必要はありません。
フレームワークを超えて
また、Composerのオートローダを使いドメインモデルをもっと自由に配置するという方法も考えられます。
なお、CodeIgniter 3.0でComposerのオートローダを使うには、$config['composer_autoload']
を設定する必要があります(Auto-loading Resources 参照)。
例えば、application/models
に以下のようにドメインモデルを配置するとすると、
application/
└─ models/
├── Entity/
├── Repository/
└── Service/
composer.json
に以下のようにオートロードの設定を追加します。ここでは、名前空間をApp\Model
としています。
composer.json
"autoload": {
"psr-4": {
"App\\Model\\": "application/models/"
}
}
Composerのオートローダを更新します。
$ composer dump-autoload
モデルファイルは以下のようになり、
application/models/Repository/ProjectRepository.php
<?php
namespace App\Model\Repository;
use CI_Model;
use App\Model\Entity\Project;
class ProjectRepository extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->load->database();
}
...
}
コントローラは以下のようになります。
application/controllers/Project.php
<?php
use App\Model\Repository\ProjectRepository;
class Project extends MY_Controller
{
public $repository;
public function __construct()
{
parent::__construct();
$this->repository = new ProjectRepository();
}
...
}
もはや、CodeIgniterの$this->load->model()
メソッドを使う必要はありません。というか使えません。しかし、フレームワーク固有のメソッドに固執する必要はありません。
上記では、application/models
としましたが、PSR-4に従う限り、application/domain
でもapplication/foo
でもどこにでも好きな場所に配置可能です。
ファットコントローラ撲滅運動
こんなスライドがありました。ご参考まで。
参考
Date: 2015/10/21