Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Aplikasi Laravel anda dengan Repositori tidak masuk akal

Aplikasi Laravel anda dengan Repositori tidak masuk akal

PHPz
PHPzasal
2024-08-02 09:42:23905semak imbas

Your Laravel application with Repository doesn

Saya telah melihat selama bertahun-tahun banyak pembangun menggunakan corak Repositori dengan Laravel, cuba menggunakan konsep seni bina bersih pada aplikasi mereka, tetapi sering salah faham konsep umum menggunakan rangka kerja seperti Laravel .

Sebelum saya mula dan perlu mengelak beberapa perkara yang saya tahu anda mungkin akan bertindak demikian, saya jelaskan: ini adalah pendapat saya sebagai seorang jurutera perisian yang telah bekerja dengan beberapa bahasa, rangka kerja, membina perisian dari awal dan mengekalkan pangkalan kod lama. Kata saya bukanlah muktamad, dan seperti biasa, saya percaya jawapan yang paling boleh diterima untuk mana-mana soalan kejuruteraan perisian ialah: “Ia bergantung pada perkara yang anda sanggup tukar untuk menyelesaikan masalah anda.”

Jadi, tanpa berlengah lagi, mari kita masuk ke subjek.

Apakah seni bina Bersih?

Clean Architecture ialah falsafah reka bentuk perisian yang bertujuan untuk mencipta sistem yang mudah diselenggara, diuji dan difahami. Ia menekankan pengasingan kebimbangan dan penciptaan sempadan antara bahagian sistem yang berlainan untuk memastikan perubahan dalam satu bahagian tidak memberi kesan buruk kepada bahagian lain. Seni bina ini dipopularkan oleh Robert C. Martin (Uncle Bob) dan sering digunakan untuk membimbing organisasi kod dengan cara yang tahan terhadap perubahan dalam peraturan perniagaan atau keperluan teknikal.

Ringkasnya, apa yang dicadangkan oleh Bob ialah aplikasi anda harus dibahagikan kepada lapisan yang mengikut prinsip utama untuk membolehkan logik perniagaan anda dipisahkan daripada sebarang pergantungan luaran, memberikan mereka mobiliti dan konteks tanggungjawab tunggal. Tetapi ini tidak akan menjadi artikel seni bina yang bersih; Saya hanya mahu meletakkan kami pada halaman yang sama tentangnya.

Bagaimana dengan Laravel dan Seni Bina Bersih?

Mengenai rangka kerja, kita bercakap tentang gandingan kebergantungan yang ketat. Anda mungkin tidak memilih Laravel untuk menggunakan Doktrin dengannya; anda mungkin memilihnya untuk menggunakan Eloquent. Perkara yang sama berlaku untuk mana-mana bahagian fungsi rangka kerja yang mungkin anda temui — anda memilih rangka kerja untuk kelajuan dan kemudahan pembangunan.

Jadi, soalan saya ialah: Mengapa anda menambah lapisan kerumitan tambahan pada sesuatu yang anda pilih untuk menjadi mudah?

Tunggu, jangan benci saya kerana mengatakan ini. Anda masih boleh menyesuaikan atau menggunakan seni bina bersih dengan Laravel, tetapi aspek paling penting dalam sebarang keputusan seni bina ialah mempunyai pemahaman yang jelas tentang perkara yang anda cuba capai dan kebaikan dan keburukan pilihan tersebut.

Ini keputusan yang sukar, dan anda boleh mengubah fikiran anda di tengah-tengah pelaksanaan. Perisian tidak boleh berubah, bukan? Saya mempunyai artikel lengkap tentang kualiti perisian di mana saya menaikkan bendera ini.

Apa pun, kembali ke Laravel dan seni bina yang bersih. Salah satu pendekatan yang paling menjengkelkan, pada pendapat saya yang sederhana, ialah penggunaan corak Repositori dengan Eloquent, dan inilah yang mendorong saya untuk menulis artikel ini.

Corak Repositori

Corak Repositori ialah corak reka bentuk yang menjadi pengantara antara domain dan lapisan pemetaan data, bertindak sebagai koleksi dalam memori objek domain. Ia bertujuan untuk memisahkan domain dan lapisan pemetaan data.

Jadi, definisi Repositori ialah entiti domain. kenapa? Kerana ia berinteraksi dengan domain dan mentakrifkan cara infrastruktur berinteraksi dengan domain, bertindak sebagai kontrak antara Domain dan lapisan Infrastruktur aplikasi kami.

Corak Repositori pada Laravel

Pertama, izinkan saya menunjukkan kepada anda pelaksanaan buruk corak Repositori yang sering saya lihat dalam aplikasi Laravel dan kemudian membetulkannya untuk anda:

// app/Repositories/UserRepositoryInterface.php
<?php

namespace App\Repositories;

interface UserRepositoryInterface
{
  // ...methods definitions
}
// app/Repositories/UserRepository.php
<?php

namespace App\Repositories;

class UserRepository implements UserRepositoryInterface
{
   // ...implementation
}

Seperti yang anda boleh lihat dalam kod di atas, "kontrak" dengan domain dan infrastruktur tidak ditakrifkan di dalam domain, tetapi di dalam infrastruktur itu sendiri. Ya, ruang nama Apl ialah sebahagian daripada Lapisan Aplikasi dan ia mengandungi semua bahan bukan domain.

Sekarang, mari lihat bagaimana saya akan melaksanakan perkara yang sama:

// domain/Repositories/UserRepositoryInterface.php
<?php

namespace Domain\Repositories;

interface UserRepositoryInterface
{
  // ...methods definitions
}
// app/Repositories/UserRepository.php
<?php

namespace App\Repositories;

use Domain\Repositories\UserRepositoryInterface;

class UserRepository implements UserRepositoryInterface
{
   // ...implementation
}

Perhatikan bahawa kini kami mempunyai lapisan domain yang betul dan lapisan aplikasi. Ia agak mudah untuk mendapatkannya, bukan?

Corak Repositori dengan Fasih

Sekarang, mari kita fikirkan sedikit. Memandangkan Antara Muka Repositori kini merupakan sebahagian daripada Domain, ini bermakna kita tidak boleh menyuntik kebergantungan daripada lapisan lain ke dalamnya. Berikut ialah contoh buruk untuk menerangkannya:

// app/Repositories/UserRepositoryInterface.php
<?php

namespace App\Repositories;

use App\Models\User;

interface UserRepositoryInterface
{
  public function find(int $id): User|null;
  // ...other methods
}

Belum jelas lagi? Biar saya mengalihkannya ke lapisan domain:

// domain/Repositories/UserRepositoryInterface.php
<?php

namespace Domain\Repositories;

use App\Models\User;

interface UserRepositoryInterface
{
  public function find(int $id): User|null;
  // ...other methods
}

Nampak masalahnya? Kami menyuntik model Eloquent yang merupakan sebahagian daripada lapisan infrastruktur ke dalam domain kami. Ini menggabungkan domain kami dengan Eloquent, yang mengalahkan tujuan corak Repositori.

But how do we solve it? Well, it is not as hard as you might think. You probably already heard about Entities, right? So, let’s fix it:

// domain/Repositories/UserRepositoryInterface.php
<?php

namespace Domain\Repositories;

use Domain\Entities\User;

interface UserRepositoryInterface
{
  public function find(int $id): User|null;
  // ...other methods
}
// domain/Entities/User.php
<?php

namespace Domain\Entities;

class User
{
  public function __construct(
    public int $id;
    public string $name;
    public string $email;
  ) {}
  // ...other properties and methods
}

Our domain layer is now clean from external dependencies, and if we want to move the whole domain to another framework, we can do it.

Now, how do we implement our Repository in our Laravel application? Let me show you:

// app/Repositories/EloquentUserRepository.php
<?php

namespace App\Repositories;

use Domain\Repositories\UserRepositoryInterface;
use Domain\Entities\User;
use App\Models\User as EloquentUser;

class EloquentUserRepository implements UserRepositoryInterface
{
    public function find(int $id): ?User {
        $eloquentUser = EloquentUser::find($id);
        return $eloquentUser ? $this->toDomain($eloquentUser): null;
    }

    private function toDomain(EloquentUser $eloquentUser): User
    {
        return new User(
          $eloquentUser->id, 
          $eloquentUser->name, 
          $eloquentUser->email
        );
    }
}

Now we have a proper implementation of the Repository pattern in Laravel using Eloquent. You can create any other Repository implementation, such as PDOUserRepository.php, DoctrineUserRepository.php, and many others without injecting any dependency into your Domain layer.

Do You Really Need to Use Repository?

Back to what I said in the subject of this article, I’ll complement that, in my humble opinion, using the Repository Pattern with Laravel is just overengineering, and you need a really good reason to do it.

You are adding an extra layer of complexity to your application that you may not need at all, or even worse, it will not guarantee that your business logic is actually isolated into the Domain layer.

What are you trying to achieve here? Think about it. You might end up missing out on many nice functionalities from Laravel or at least making their usage overly complicated.

Are you not sure if Laravel is the best framework for your application and you might move your application to Symfony in the future? Sure, go for the Domain and the Repository. Do you need to replace your SQL database with a NoSQL database later? Maybe it is a good justification. But do you really need it, or is it just charm?

One common argument is that the Repository helps to put some business logic into a separate layer. This normally gives me the creeps because there are better approaches for splitting your logic. Repositories are just for acting as a middle layer to connect the data layer and domain, nothing else. If you want to split your business logic, you should make use of something else — but this is another subject.

Conclusion

In conclusion, while the Repository pattern and clean architecture principles offer significant benefits in terms of maintainability and separation of concerns, their application in a Laravel context often introduces unnecessary complexity. Laravel is designed for simplicity and rapid development, and adding layers of abstraction can complicate this process.

Before implementing the Repository pattern, it is essential to evaluate your project’s specific needs. If decoupling your domain logic from Laravel’s infrastructure is a genuine necessity due to future migrations or a need for flexibility, then the complexity might be warranted. However, for many Laravel applications, leveraging Eloquent directly aligns better with the framework’s strengths and keeps the codebase simpler and more maintainable.

Ultimately, the decision should be driven by a clear understanding of your project’s requirements, balancing the trade-offs involved. Overengineering can lead to more problems than it solves, so aim to keep your solutions as straightforward as possible while still achieving your design goals. The primary objective of any architecture is to solve problems, not to create new ones.

Atas ialah kandungan terperinci Aplikasi Laravel anda dengan Repositori tidak masuk akal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn