PHP Academy · Pelajaran

Penyongsangan Kebergantungan dalam Amalan

Sambungkan adapter kepada teras dengan penyongsangan kebergantungan.

Pelajaran 4 daripada 413 langkah

Penyongsangan Kebergantungan dalam Amalan ialah pelajaran PHP Academy percuma di CoddyKit. Ini ialah pelajaran 4 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.

Inversi berbanding Suntikan

Orang sering mencampuradukkan dua idea yang berbeza. Suntikan Kebergantungan ialah teknik: masukkan rakan usaha bersama, bukannya membinanya. Inversi Kebergantungan (D dalam SOLID) ialah prinsip: dasar tahap tinggi dan perincian tahap rendah kedua-duanya bergantung pada abstraksi, dan abstraksi itu dimiliki oleh modul tahap tinggi. Pelajaran ini menerangkan cara merealisasikan prinsip kedua — menyambungkan penyesuai konkrit kepada teras yang mentakrifkan antara muka.

Prinsip Itu, dengan Tepat

DIP menyatakan:

  • Modul tahap tinggi tidak sepatutnya bergantung pada modul tahap rendah. Kedua-duanya bergantung pada abstraksi.
  • Abstraksi tidak sepatutnya bergantung pada perincian. Perincian bergantung pada abstraksi.

Bahagian yang halus ialah: antara muka dimiliki oleh pengguna, bukannya pelaksana. Domain anda mengisytiharkan PaymentGateway; penyesuai Stripe mematuhinya — bukannya sebaliknya.

Takrifkan Abstraksi dalam Teras

Letakkan antara muka bersebelahan dengan kod yang memerlukannya dan ungkapkannya dalam istilah domain. Jangan biarkan jenis Stripe meresap masuk.

<?php
// src/Billing/Application/Port/PaymentGateway.php
interface PaymentGateway
{
    public function charge(Money $amount, CardToken $token): ChargeId;
}

final class Money {
    public function __construct(public readonly int $cents, public readonly string $currency) {}
}
final class CardToken { public function __construct(public readonly string $value) {} }
final class ChargeId { public function __construct(public readonly string $value) {} }

Sesuaikan Penyesuai Dengannya

Penyesuai infrastruktur melaksanakan antara muka teras dan menterjemahkannya kepada SDK pembekal. Anak panah kebergantungan menunjuk daripada penyesuai (perincian) kepada abstraksi (dasar) — inversi telah dicapai.

<?php
final class StripePaymentGateway implements PaymentGateway
{
    public function __construct(private \Stripe\StripeClient $stripe) {}

    public function charge(Money $amount, CardToken $token): ChargeId {
        $intent = $this->stripe->paymentIntents->create([
            'amount'   => $amount->cents,
            'currency' => strtolower($amount->currency),
            'payment_method' => $token->value,
            'confirm'  => true,
        ]);
        return new ChargeId($intent->id);
    }
}

Suntikan Pembina ialah Lalai

Lakukan suntikan melalui pembina dan nyatakan jenis abstraksi. Kebergantungan menjadi jelas, tidak berubah dan mustahil untuk terlupa. Elakkan suntikan penetap dan sifat untuk rakan usaha bersama yang wajib — kedua-duanya membenarkan objek yang separa dibina.

<?php
final class CheckoutService
{
    public function __construct(
        private PaymentGateway $payments,   // abstraction, not StripeClient
        private OrderRepository $orders,
    ) {}

    public function pay(OrderId $id, CardToken $token): ChargeId {
        $order  = $this->orders->get($id);
        $charge = $this->payments->charge($order->total(), $token);
        $order->markPaid($charge);
        $this->orders->save($order);
        return $charge;
    }
}

Akar Gubahan

Semua penyambungan konkrit berlaku tepat di satu tempat — akar gubahan — sedekat mungkin dengan main()/titik masuk. Tiada bahagian lain yang membina infrastruktur. Hanya tempat inilah yang mengetahui kewujudan Stripe.

<?php
// public/index.php — composition root
$stripe   = new \Stripe\StripeClient(getenv('STRIPE_SECRET'));
$gateway  = new StripePaymentGateway($stripe);
$orders   = new PdoOrderRepository(new PDO(getenv('DB_DSN')));
$checkout = new CheckoutService($gateway, $orders);

// Everything below depends only on abstractions
$controller = new CheckoutController($checkout);

Menyambung dengan Bekas DI

Untuk aplikasi yang tidak remeh, bekas (PHP-DI, Symfony) mengautomatikkan penyambungan. Langkah utamanya ialah mengikat antara muka kepada pelaksanaan. Penyambungan automatik menyelesaikan pembina berdasarkan jenis; anda hanya perlu mengisytiharkan pemetaan antara muka→kelas.

<?php
use function DI\autowire;
use function DI\get;

return [
    PaymentGateway::class => autowire(StripePaymentGateway::class),
    OrderRepository::class => autowire(PdoOrderRepository::class),
    \Stripe\StripeClient::class => fn() => new \Stripe\StripeClient(getenv('STRIPE_SECRET')),
    PDO::class => fn() => new PDO(getenv('DB_DSN')),
];

Pertukaran Penyesuai Membuktikan Prinsipnya

Oleh sebab teras hanya bergantung pada PaymentGateway, pertukaran pembekal atau pengujian di luar talian hanya memerlukan perubahan satu baris pada penyambungan. Berikut ialah objek palsu yang digunakan dalam ujian unit — CheckoutService tidak berubah dan tidak pernah mengimport Stripe.

<?php
final class FakeGateway implements PaymentGateway {
    public array $charges = [];
    public function charge(Money $a, CardToken $t): ChargeId {
        $this->charges[] = $a;
        return new ChargeId('ch_test_' . count($this->charges));
    }
}

$fake = new FakeGateway();
$id = $fake->charge(new Money(2500, 'EUR'), new CardToken('tok_visa'));
echo $id->value, ' charges=', count($fake->charges), PHP_EOL; // ch_test_1 charges=1

Elakkan Perangkap Pencari Perkhidmatan

Menyuntik bekas itu sendiri dan mendapatkan kebergantungan di dalam kaedah ialah corak anti pencari perkhidmatan. Ia menyembunyikan kebergantungan, menggagalkan pemeriksaan jenis dan mengikat semula kod anda kepada bekas. Suntik perkara yang diperlukan secara jelas.

<?php
// ANTI-PATTERN: hidden dependencies, container leaks everywhere
final class BadCheckout {
    public function __construct(private ContainerInterface $c) {}
    public function pay($id, $token) {
        $gateway = $this->c->get(PaymentGateway::class); // hidden!
        // ...
    }
}

Di Mana Bekas Boleh Muncul

Bekas hanya wajar berada dalam satu lapisan: akar gubahan serta gam rangka kerja di sekelilingnya (contohnya, kilang pengawal). Domain dan kelas aplikasi mesti kekal bebas daripada bekas — kedua-duanya menerima objek biasa melalui pembina dan boleh dibuat secara manual. Ujian yang baik: bolehkah anda menyambungkan keseluruhan aplikasi dalam satu fail PHP tanpa bekas? Jika boleh, kebergantungan anda dinyatakan dengan jujur.

Penyambungan Malas Tanpa Pencarian Perkhidmatan

Sesetengah kebergantungan mahal untuk dibina atau hanya diperlukan secara bersyarat. Elakkan menyuntik bekas — sebaliknya suntik closure kilang. Kebergantungan kekal jelas dan ditaip, manakala pembinaannya ditangguhkan sehingga benar-benar digunakan.

<?php
final class ReportService
{
    /** @param Closure():PaymentGateway $gatewayFactory */
    public function __construct(private Closure $gatewayFactory) {}

    public function refundIfNeeded(bool $needed): void {
        if (!$needed) return;
        $gateway = ($this->gatewayFactory)(); // built only when required
        // $gateway->charge(...) etc.
    }
}

// Composition root supplies the factory, not the container
$svc = new ReportService(fn() => new StripePaymentGateway($stripe ?? null));
echo 'lazy dependency wired', PHP_EOL;

Ujian Ringkas

Siapakah yang sepatutnya memiliki antara muka PaymentGateway?

Ringkasan

Anda telah menyambungkan penyesuai kepada teras dengan cara yang betul:

  • Inversi ≠ suntikan: suntikan ialah mekanisme, manakala inversi ialah pemilikan abstraksi oleh pengguna.
  • Teras mentakrifkan antara muka; penyesuai infrastruktur mematuhinya.
  • Gunakan suntikan pembina bagi abstraksi; lakukan semua penyambungan konkrit dalam satu akar gubahan (atau konfigurasi bekas yang mengikat antara muka→kelas).
  • Pertukaran penyesuai dan penggunaan objek palsu dalam ujian menjadi perubahan satu baris.
  • Elakkan corak anti pencari perkhidmatan — letakkan bekas di pinggir sahaja.
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 “Penyongsangan Kebergantungan dalam Amalan” percuma?

Ya — teks penuh “Penyongsangan Kebergantungan dalam Amalan” 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 “Penyongsangan Kebergantungan dalam Amalan”?

Sambungkan adapter kepada teras dengan penyongsangan kebergantungan. 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 4 daripada 4.

Berapa lamakah pelajaran “Penyongsangan Kebergantungan dalam Amalan” 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