Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mencipta aplikasi domain berfokus. Pendekatan Symfony (Bahagian 1)

Mencipta aplikasi domain berfokus. Pendekatan Symfony (Bahagian 1)

Patricia Arquette
Patricia Arquetteasal
2024-11-03 10:52:29665semak imbas

pengenalan

Ini adalah siaran pertama siri yang telah saya putuskan untuk dibuat untuk menerangkan cara saya mengatur aplikasi symfony saya dan cara saya cuba menulis kod sebagai berorientasikan domain yang mungkin.
Di bawah, anda boleh menemui gambarajah alir yang akan saya gunakan semasa semua bahagian siri. Dalam setiap siaran, saya akan memfokuskan pada bahagian konkrit rajah dan saya akan cuba menganalisis proses yang terlibat dan mengesan bahagian mana yang akan menjadi milik domain kami dan cara memisahkan daripada bahagian lain menggunakan lapisan luaran.

Creating focused domain applications. A Symfony approach (Part 1)

Memecahkan pemprosesan data

Dalam bahagian pertama ini, kami akan menumpukan pada proses pengekstrakan dan pengesahan data. Untuk proses pengekstrakan data, kami akan menganggap bahawa data permintaan diformatkan sebagai JSON.

Mengekstrak data

Berdasarkan fakta bahawa kami tahu bahawa data permintaan terdapat dalam muatan permintaan JSON, mengekstrak muatan permintaan (dalam kes ini mengekstrak bermakna mendapatkan tatasusunan daripada muatan JSON) adalah semudah menggunakan fungsi php json_decode.

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request,): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        // validate data
    }
}

Mengesahkan data

Untuk mengesahkan data, kami memerlukan tiga elemen:

  • Satu untuk mentakrifkan peraturan pengesahan.
  • Satu untuk menukar data yang diminta menjadi objek yang sah.
  • Satu untuk mengesahkan data yang diekstrak berdasarkan peraturan tersebut.

Mentakrifkan peraturan pengesahan

Untuk yang pertama, kami akan mencipta DTO (Objek Pemindahan Data) yang akan mewakili data masuk dan kami akan menggunakan atribut kekangan pengesahan Symfony untuk menentukan cara data ini mesti disahkan.

readonly class UserInputDTO {
    public function __construct(
        #[NotBlank(message: 'Email cannot be empty')]
        #[Email(message: 'Email must be a valid email')]
        public string $email,
        #[NotBlank(message: 'First name cannot be empty')]
        public string $firstname,
        #[NotBlank(message: 'Last name cannot be empty')]
        public string $lastname,
        #[NotBlank(message: 'Date of birth name cannot be empty')]
        #[Date(message: 'Date of birth must be a valid date')]
        public string $dob
    ){}
}

Seperti yang anda lihat, kami telah menentukan peraturan pengesahan data input kami dalam DTO yang dibuat baru-baru ini. Peraturan ini adalah seperti berikut:

  • e-mel: Tidak boleh kosong dan mestilah e-mel yang sah
  • nama pertama: Tidak boleh kosong
  • nama keluarga: Tidak boleh kosong
  • dob (Tarikh lahir): Tidak boleh kosong dan mesti tarikh yang sah.

Menyahnormalkan data permintaan ke dalam DTO

Untuk yang kedua, kami akan menggunakan komponen Symfony normalizer yang dengannya kami akan dapat memetakan permintaan data masuk ke dalam DTO kami.

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request, SerializerInterface $serializer): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class);
    }
}

Seperti yang ditunjukkan di atas, kaedah nyahnormalkan melakukan perkara dan dengan satu baris kod, kami mendapatkan DTO kami diisi dengan data masuk.

Mengesahkan DTO

Akhir sekali, untuk mengesahkan data kami akan bergantung pada perkhidmatan pengesah Symfony yang akan menerima contoh DTO kami yang dinyahnormalkan baru-baru ini (yang akan membawa data masuk) dan akan mengesahkan data mengikut peraturan DTO.

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request,): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        // validate data
    }
}

Mengenal pasti domain

Setakat ini, kami telah membahagikan proses Mengekstrak dan Mengesahkan Data kepada empat bahagian:

  • Ekstrak tatasusunan daripada muatan permintaan JSON.
  • Buat DTO untuk mewakili data masuk dan peraturan pengesahannya.
  • Nyahnormalkan tatasusunan menjadi DTO yang mengandungi peraturan pengesahan.
  • Sahkan DTO.

Persoalannya sekarang ialah: Manakah antara bahagian ini yang tergolong dalam domain kami?
Untuk menjawab soalan, Mari analisa proses yang terlibat:

1.- Mengekstrak data: Bahagian ini hanya menggunakan fungsi "json_decode" untuk mengubah data masuk daripada json kepada tatasusunan. Ia tidak menambah logik perniagaan jadi ini bukan milik domain.

2.- DTO: DTO mengandungi sifat yang dikaitkan dengan data input dan cara ia akan disahkan. Ini bermakna DTO mengandungi peraturan perniagaan (peraturan pengesahan) supaya ia tergolong dalam domain.

3.- Nyahnormalkan data: Bahagian ini hanya menggunakan perkhidmatan infrastruktur (komponen rangka kerja) untuk menyahnormalkan data menjadi objek. Ini tidak mengandungi peraturan perniagaan jadi ini bukan milik domain kami.

4.- Mengesahkan data: Dengan cara yang sama seperti proses Nyahnormalkan data, proses data yang mengesahkan juga menggunakan perkhidmatan infrastruktur (komponen rangka kerja) untuk mengesahkan data yang masuk . Ini tidak mengandungi peraturan perniagaan kerana ia ditakrifkan dalam DTO jadi ia juga bukan sebahagian daripada domain kami.

Selepas menganalisis mata terakhir, kami boleh membuat kesimpulan bahawa hanya DTO akan menjadi sebahagian daripada domain kami. Kemudian, apa yang kita lakukan dengan kod yang lain?

Mencipta perkhidmatan aplikasi

Secara peribadi, saya suka memasukkan proses jenis ini (mengekstrak, menyahnormalkan dan mengesahkan data) ke dalam lapisan aplikasi atau lapisan perkhidmatan. Kenapa ?, mari perkenalkan lapisan aplikasi.

Lapisan Aplikasi

Ringkasnya, lapisan aplikasi bertanggungjawab untuk orkestrasi dan penyelarasan, meninggalkan logik perniagaan kepada lapisan domain. Selain itu, ia bertindak sebagai perantara antara lapisan domain dan lapisan luaran seperti lapisan pembentangan (UI) dan lapisan infrastruktur.
Bermula daripada definisi di atas, kita boleh memasukkan proses Mengekstrak, Menyahnormalkan dan Mengesahkan ke dalam perkhidmatan dalam lapisan aplikasi sejak:

  • Ia menyelaraskan proses data masuk.
  • Ia menggunakan perkhidmatan infrastruktur (fungsi PHP JSON, komponen normalisasi Symfony dan komponen pengesahan Symfony) untuk memproses data masuk.
  • Ia menggunakan peraturan domain dengan menyerahkan DTO kepada perkhidmatan infrastruktur pengesahan.

Sempurna, kami akan mencipta perkhidmatan aplikasi untuk menguruskan proses ini. Bagaimana kita akan melakukannya? Bagaimana kita hendak menguruskan tanggungjawab?

Menganalisis tanggungjawab

Prinsip Tanggungjawab Tunggal (SRP) menyatakan bahawa setiap kelas harus bertanggungjawab untuk hanya satu bahagian tingkah laku aplikasi. Jika kelas mempunyai pelbagai tanggungjawab, ia menjadi lebih sukar untuk difahami, diselenggara dan diubah suai.

Bagaimanakah ini memberi kesan kepada kita? Mari analisanya.
Setakat ini, kami tahu bahawa perkhidmatan aplikasi kami mesti mengekstrak, menyahnormalkan dan mengesahkan data masuk. Mengetahui perkara ini, adalah mudah untuk mengeluarkan tanggungjawab berikut:

  • Ekstrak data
  • Nyahnormalkan data
  • Sahkan data

Perlukah kita membahagikan tanggungjawab ini kepada 3 perkhidmatan yang berbeza? Saya tidak fikir begitu. Biar saya terangkan.

Seperti yang telah kita lihat, setiap tanggungjawab diuruskan oleh fungsi atau komponen infrastruktur:

  • Mengekstrak tanggungjawab: Fungsi json_decode PHP
  • Nyahnormalkan tanggungjawab data: Komponen penormal Symfony
  • Sahkan tanggungjawab data: Komponen pengesahan Symfony

Memandangkan perkhidmatan aplikasi boleh mewakilkan tanggungjawab ini kepada perkhidmatan infrastruktur, kami boleh membuat tanggungjawab yang lebih abstrak (Proses data) dan menyerahkannya kepada perkhidmatan aplikasi.

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request,): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        // validate data
    }
}

Seperti yang ditunjukkan di atas, perkhidmatan aplikasi DataProcessor menggunakan fungsi json_decode dan perkhidmatan normalizer dan validator Symfony untuk memproses permintaan input dan mengembalikan DTO yang baru dan disahkan. Jadi kita boleh katakan bahawa perkhidmatan DataProcessor:

  • Menyelaras semua tugas yang berkaitan dengan pemprosesan data input.
  • Berkomunikasi dengan dunia luar (perkhidmatan infrastruktur) dengan peraturan perniagaan domain (DTO).

Seperti yang anda mungkin perasan, perkhidmatan DataProcessor melemparkan Symfony ValidationException apabila proses pengesahan menemui ralat. Dalam siaran seterusnya siri ini, kami akan belajar cara menggunakan peraturan perniagaan kami untuk menstruktur ralat dan akhirnya membentangkannya kepada pelanggan.

Saya tahu bahawa kami boleh mengalih keluar perkhidmatan DataProcessor dan menggunakan MapRequestPayload sebagai lapisan aplikasi perkhidmatan untuk mengekstrak, menyahnormalkan dan mengesahkan data tetapi, memandangkan konteks artikel ini, saya fikir ia lebih mudah untuk tulis dengan cara ini.

Kesimpulan

Dalam artikel pertama ini, kami telah menumpukan pada proses Pengekstrakan dan Pengesahan data daripada rajah alir. Kami telah menyenaraikan tugasan yang terlibat dalam proses ini dan kami telah mempelajari cara untuk mengesan bahagian mana yang tergolong dalam domain tersebut.
Mengetahui bahagian mana yang dimiliki oleh domain, kami telah menulis perkhidmatan lapisan aplikasi yang menghubungkan perkhidmatan infrastruktur yang diperintah oleh domain dan menyelaraskan proses pengekstrakan dan pengesahan data.
Dalam artikel seterusnya, kami akan meneroka hangat untuk menentukan peraturan perniagaan kami untuk mengurus pengecualian dan kami juga akan mencipta perkhidmatan domain yang akan bertanggungjawab mengubah DTO Input menjadi entiti yang berterusan.

Atas ialah kandungan terperinci Mencipta aplikasi domain berfokus. Pendekatan Symfony (Bahagian 1). 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