PHP Academy · Pelajaran

Daripada Seni Bina Berlapis kepada Seni Bina Bersih

Fahami sebab kebergantungan sepatutnya menghala ke dalam.

Pelajaran 1 daripada 413 langkah

Daripada Seni Bina Berlapis kepada Seni Bina Bersih ialah pelajaran PHP Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran PHP Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus PHP Academy merangkumi sejumlah 4 pelajaran.

Mengapa Seni Bina Bersih

Anda sudah mengetahui susunan klasik PHP tiga lapisan: Pengawal → Perkhidmatan → Repositori → Pangkalan Data. Susunan ini berfungsi, tetapi logik perniagaan akhirnya bergandingan dengan Eloquent, Doctrine, permintaan web dan kitar hayat rangka kerja. Seni Bina Bersih membalikkan arah kebergantungan supaya domain anda tidak mengetahui apa-apa tentang infrastruktur. Hasilnya: kes penggunaan yang boleh diuji, penyesuai yang boleh ditukar dan pangkalan kod yang mampu bertahan melalui naik taraf rangka kerja.

Peraturan Kebergantungan

Satu-satunya peraturan Seni Bina Bersih: kebergantungan kod sumber hanya menghala ke dalam. Bulatan dalam (entiti, kes penggunaan) tidak boleh merujuk bulatan luar (pengawal, pemeta hubungan objek, rangka kerja). Pada masa jalan, aliran kawalan bergerak ke luar melalui antara muka, tetapi pada masa penyusunan dan pengimportan, tiada apa-apa dari dalam mengimport sesuatu dari luar.

  • Entiti: peraturan perusahaan
  • Kes Penggunaan: peraturan aplikasi
  • Penyesuai: pengawal, penyampai, get laluan
  • Rangka Kerja & Pemacu: pangkalan data, web, rangkaian

Contoh Lapisan yang Bergandingan

Inilah jenis perkhidmatan yang dihantar bersama kebanyakan aplikasi PHP. Perhatikan bahawa logik domain terjerat dengan Eloquent dan respons web. Anda tidak boleh menguji peraturan diskaun secara unit tanpa pangkalan data dan rangka kerja.

<?php
class OrderService
{
    public function place(Request $request)
    {
        $user = User::find($request->user_id); // Eloquent
        $total = 0;
        foreach ($request->items as $i) {
            $total += Product::find($i['id'])->price * $i['qty'];
        }
        if ($user->is_vip) {
            $total *= 0.9; // business rule trapped in infra code
        }
        Order::create(['user_id' => $user->id, 'total' => $total]);
        return response()->json(['total' => $total]);
    }
}

Entiti: Domain Tanpa Rangka Kerja

Entiti mengekodkan peraturan seluruh perusahaan dan tidak bergantung pada apa-apa. PHP biasa, tanpa anotasi dan tanpa kelas asas daripada pemeta hubungan objek. Ia boleh dibina sepenuhnya dalam ujian.

<?php
final class Money
{
    public function __construct(public readonly int $cents) {
        if ($cents < 0) throw new InvalidArgumentException('negative money');
    }
    public function multiply(float $factor): self {
        return new self((int) round($this->cents * $factor));
    }
}

final class Order
{
    /** @param array<int,int> $lineCents */
    public function __construct(private array $lineCents, private bool $vip) {}
    public function total(): Money {
        $sum = array_sum($this->lineCents);
        $money = new Money($sum);
        return $this->vip ? $money->multiply(0.9) : $money;
    }
}

echo (new Order([1000, 2000], true))->total()->cents, PHP_EOL; // 2700

Kes Penggunaan Memiliki Aliran Kerja

Kes penggunaan (pengantara) menyelaraskan entiti dan berhubung dengan dunia luar hanya melalui antara muka (port). Ia menerima objek pemindahan data permintaan dan mengembalikan objek pemindahan data respons — tidak pernah objek web.

<?php
interface OrderRepository {
    public function save(Order $order): void;
}

final class PlaceOrder
{
    public function __construct(private OrderRepository $orders) {}

    public function execute(array $lineCents, bool $vip): int {
        $order = new Order($lineCents, $vip);
        $this->orders->save($order);
        return $order->total()->cents;
    }
}

Sempadan ialah Antara Muka

Kes penggunaan mengisytiharkan antara muka OrderRepository yang diperlukannya. Antara muka itu berada dalam bulatan dalam; pelaksanaan konkrit Eloquent/Doctrine berada di luar dan bergantung ke dalam. Inilah Prinsip Pembalikan Kebergantungan (DIP) yang diterapkan pada sempadan seni bina.

Arah kebergantungan kod sumber: EloquentOrderRepository → OrderRepository (antara muka), tidak pernah sebaliknya.

<?php
// Lives in infrastructure layer, points INWARD to the domain interface
final class EloquentOrderRepository implements OrderRepository
{
    public function save(Order $order): void {
        OrderModel::create(['total' => $order->total()->cents]);
    }
}

Menguji Tanpa Infrastruktur

Oleh sebab kes penggunaan bergantung pada antara muka, ujian menyuntik objek palsu. Tiada pangkalan data dan tiada proses pemulaan rangka kerja — ujian unit sepantas mikrosaat yang mengesahkan tingkah laku perniagaan tulen.

<?php
final class InMemoryOrders implements OrderRepository {
    public array $saved = [];
    public function save(Order $o): void { $this->saved[] = $o; }
}

$repo = new InMemoryOrders();
$useCase = new PlaceOrder($repo);
$total = $useCase->execute([1000, 2000], true);

assert($total === 2700);
assert(count($repo->saved) === 1);
echo "PASS total=$total saved=" . count($repo->saved) . PHP_EOL;

Pengawal Menjadi Penyesuai Nipis

Pengawal kini ialah penyesuai: ia menterjemahkan permintaan web kepada panggilan kes penggunaan dan hasilnya kembali kepada respons web. Ia tidak mengandungi peraturan perniagaan. Tukar perkhidmatan web kepada CLI atau pekerja baris gilir, dan kes penggunaan tidak berubah.

<?php
final class OrderController
{
    public function __construct(private PlaceOrder $placeOrder) {}

    public function store(Request $request): JsonResponse {
        $total = $this->placeOrder->execute(
            lineCents: $request->input('lineCents'),
            vip: (bool) $request->input('vip'),
        );
        return new JsonResponse(['total' => $total], 201);
    }
}

Seni Bina yang Menonjolkan Domain

Struktur folder harus jelas menonjolkan domain, bukannya rangka kerja. Elakkan Controllers/ dan Models/ di peringkat teratas. Susun mengikut keupayaan supaya pendatang baharu dapat melihat fungsi aplikasi.

  • src/Ordering/Domain/ — entiti, objek nilai
  • src/Ordering/Application/ — kes penggunaan, antara muka port
  • src/Ordering/Infrastructure/ — repositori Eloquent, pengawal web

Setiap konteks terbatas ialah folder peringkat teratas; rangka kerja berada di sempadan.

Menguatkuasakan Peraturan Kebergantungan

Disiplin akan merosot tanpa alat. Gunakan deptrac atau phparkitect dalam penyepaduan berterusan untuk menggagalkan binaan apabila lapisan domain mengimport lapisan infrastruktur. Peraturan itu menjadi jaminan masa penyusunan, bukannya sekadar harapan semasa semakan kod.

# deptrac.yaml
deptrac:
  layers:
    - name: Domain
      collectors: [{ type: directory, value: src/.*/Domain/.* }]
    - name: Application
      collectors: [{ type: directory, value: src/.*/Application/.* }]
    - name: Infrastructure
      collectors: [{ type: directory, value: src/.*/Infrastructure/.* }]
  ruleset:
    Domain: []                       # Domain may depend on nothing
    Application: [Domain]
    Infrastructure: [Application, Domain]

Melintasi Sempadan dengan Objek Pemindahan Data

Untuk menghalang entiti daripada meresap ke luar, data yang melintasi sempadan dihantar sebagai objek pemindahan data yang ringkas, bukannya entiti atau model pemeta hubungan objek. Kes penggunaan mengembalikan struktur rata yang boleh disiri oleh penyesuai, supaya objek domain tidak pernah meninggalkan teras dan lapisan luar tidak pernah mendapat pemegang kepada keadaan dalaman.

<?php
final class OrderSummary // boundary DTO, no behavior, no domain types
{
    public function __construct(
        public readonly string $orderId,
        public readonly int $totalCents,
    ) {}
}

final class PlaceOrderV2 {
    public function __construct(private OrderRepository $orders) {}
    public function execute(array $lineCents, bool $vip): OrderSummary {
        $order = new Order($lineCents, $vip);
        $this->orders->save($order);
        return new OrderSummary('ord_1', $order->total()->cents);
    }
}

Semakan Pantas

Apakah arah kebergantungan yang dibenarkan di bawah Peraturan Kebergantungan?

Ulang Kaji

Anda telah beralih daripada susunan lapisan yang bergandingan kepada Seni Bina Bersih:

  • Peraturan Kebergantungan: kebergantungan kod sumber hanya menghala ke dalam.
  • Entiti mengandungi peraturan perusahaan dalam PHP tanpa rangka kerja.
  • Kes penggunaan menyelaras melalui antara muka port, lalu mengembalikan objek pemindahan data, bukan objek web.
  • Pengawal dan repositori pemeta hubungan objek ialah penyesuai luar yang bergantung ke dalam (DIP).
  • Struktur harus jelas menonjolkan domain, dan alat seperti deptrac menguatkuasakan peraturan dalam penyepaduan berterusan.
Percuma untuk bermula

Pelajari PHP dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
49
Pelajaran
195

Soalan Lazim

Adakah pelajaran “Daripada Seni Bina Berlapis kepada Seni Bina Bersih” percuma?

Ya — teks penuh “Daripada Seni Bina Berlapis kepada Seni Bina Bersih” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus PHP Academy, tingkat taraf kepada CoddyKit PRO. Kursus PHP Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Daripada Seni Bina Berlapis kepada Seni Bina Bersih”?

Fahami sebab kebergantungan sepatutnya menghala ke dalam. Anda berlatih PHP Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan PHP Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran PHP Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “Daripada Seni Bina Berlapis kepada Seni Bina Bersih” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran PHP Academy ini?

Ya. Setiap pelajaran PHP Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Daripada Seni Bina Berlapis kepada Seni Bina Bersih
  2. Port dan Adapter Diterangkan
  3. Kes Penggunaan dan Perkhidmatan Aplikasi
  4. Penyongsangan Kebergantungan dalam Amalan
← Kembali ke PHP Academy