Saya menyelesaikan proyek besar menggunakan Laravel 4 dan harus menjawab semua pertanyaan yang Anda ajukan sekarang. Setelah membaca semua buku Laravel yang tersedia di Leanpub, dan banyak sekali Googling, saya menemukan struktur berikut.
- Satu kelas Model Eloquent per tabel data
- Satu kelas Repositori per Model Eloquent
- Kelas Layanan yang dapat berkomunikasi antara beberapa kelas Repositori.
Jadi katakanlah saya sedang membangun database film. Saya akan memiliki setidaknya kelas-kelas Model Eloquent berikut:
- Film
- Studio
- Direktur
- Aktor
- Ulasan
Sebuah kelas repositori akan merangkum setiap kelas Model Eloquent dan bertanggung jawab untuk operasi CRUD pada database. Kelas repositori mungkin terlihat seperti ini:
- MovieRepository
- StudioRepository
- DirectorRepository
- ActorRepository
- ReviewRepository
Setiap kelas repositori akan memperluas kelas BaseRepository yang mengimplementasikan antarmuka berikut:
interface BaseRepositoryInterface
{
public function errors();
public function all(array $related = null);
public function get($id, array $related = null);
public function getWhere($column, $value, array $related = null);
public function getRecent($limit, array $related = null);
public function create(array $data);
public function update(array $data);
public function delete($id);
public function deleteWhere($column, $value);
}
Kelas Service digunakan untuk merekatkan beberapa repositori bersama-sama dan berisi "logika bisnis" aplikasi yang sebenarnya. Pengontrol hanya berkomunikasi dengan kelas Layanan untuk tindakan Buat, Perbarui, dan Hapus.
Jadi, ketika saya ingin membuat rekaman Film baru di database, kelas MovieController saya mungkin memiliki metode berikut:
public function __construct(MovieRepositoryInterface $movieRepository, MovieServiceInterface $movieService)
{
$this->movieRepository = $movieRepository;
$this->movieService = $movieService;
}
public function postCreate()
{
if( ! $this->movieService->create(Input::all()))
{
return Redirect::back()->withErrors($this->movieService->errors())->withInput();
}
// New movie was saved successfully. Do whatever you need to do here.
}
Terserah Anda untuk menentukan bagaimana Anda POST data ke pengontrol Anda, tetapi katakanlah data yang dikembalikan oleh Input :: all () dalam metode postCreate () terlihat seperti ini:
$data = array(
'movie' => array(
'title' => 'Iron Eagle',
'year' => '1986',
'synopsis' => 'When Doug\'s father, an Air Force Pilot, is shot down by MiGs belonging to a radical Middle Eastern state, no one seems able to get him out. Doug finds Chappy, an Air Force Colonel who is intrigued by the idea of sending in two fighters piloted by himself and Doug to rescue Doug\'s father after bombing the MiG base.'
),
'actors' => array(
0 => 'Louis Gossett Jr.',
1 => 'Jason Gedrick',
2 => 'Larry B. Scott'
),
'director' => 'Sidney J. Furie',
'studio' => 'TriStar Pictures'
)
Karena MovieRepository seharusnya tidak mengetahui cara membuat rekaman Aktor, Sutradara, atau Studio di database, kami akan menggunakan kelas MovieService kami, yang mungkin terlihat seperti ini:
public function __construct(MovieRepositoryInterface $movieRepository, ActorRepositoryInterface $actorRepository, DirectorRepositoryInterface $directorRepository, StudioRepositoryInterface $studioRepository)
{
$this->movieRepository = $movieRepository;
$this->actorRepository = $actorRepository;
$this->directorRepository = $directorRepository;
$this->studioRepository = $studioRepository;
}
public function create(array $input)
{
$movieData = $input['movie'];
$actorsData = $input['actors'];
$directorData = $input['director'];
$studioData = $input['studio'];
// In a more complete example you would probably want to implement database transactions and perform input validation using the Laravel Validator class here.
// Create the new movie record
$movie = $this->movieRepository->create($movieData);
// Create the new actor records and associate them with the movie record
foreach($actors as $actor)
{
$actorModel = $this->actorRepository->create($actor);
$movie->actors()->save($actorModel);
}
// Create the director record and associate it with the movie record
$director = $this->directorRepository->create($directorData);
$director->movies()->associate($movie);
// Create the studio record and associate it with the movie record
$studio = $this->studioRepository->create($studioData);
$studio->movies()->associate($movie);
// Assume everything worked. In the real world you'll need to implement checks.
return true;
}
Jadi yang tersisa adalah pemisahan perhatian yang baik dan masuk akal. Repositori hanya mengetahui model Eloquent yang mereka sisipkan dan ambil dari database. Pengontrol tidak peduli dengan repositori, mereka hanya menyerahkan data yang mereka kumpulkan dari pengguna dan meneruskannya ke layanan yang sesuai. Layanan tidak peduli bagaimana data yang diterimanya disimpan ke database, itu hanya menyerahkan data relevan yang diberikan oleh pengontrol ke repositori yang sesuai.