0Pricing
PHP Academy · Pelajaran

Prinsip SOLID dalam Praktik

Terapkan lima prinsip SOLID pada kelas PHP nyata.

Prinsip SOLID dalam Praktik adalah pelajaran PHP Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar PHP Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus PHP Academy mencakup 4 pelajaran total.

Mengapa SOLID

SOLID adalah lima prinsip desain yang menjaga PHP berorientasi objek tetap fleksibel, mudah diuji, dan tahan terhadap kerusakan. Prinsip-prinsip ini bukan aturan yang harus diikuti secara membabi buta, melainkan heuristik yang mengurangi keterikatan dan memperjelas tanggung jawab. Dalam pelajaran ini, Anda akan menerapkan setiap prinsip pada kelas PHP konkret yang benar-benar akan Anda kirimkan.

  • S Tanggung Jawab Tunggal
  • O Terbuka/Tertutup
  • L Substitusi Liskov
  • I Pemisahan Antarmuka
  • D Pembalikan Dependensi

Tanggung Jawab Tunggal

Sebuah kelas seharusnya memiliki satu alasan untuk berubah. Kelas yang membuat laporan, memformatnya sebagai HTML, dan mengirimkannya melalui surel memiliki tiga alasan untuk berubah. Pisahkan penyimpanan, pemformatan, dan pengiriman.

Di bawah ini, Invoice hanya memodelkan data; perenderan dan penyimpanan dilakukan di tempat lain.

<?php
final class Invoice {
    public function __construct(
        public readonly string $number,
        public readonly int $cents
    ) {}
    public function total(): float { return $this->cents / 100; }
}

final class InvoiceRenderer {
    public function toText(Invoice $i): string {
        return sprintf('Invoice %s: $%.2f', $i->number, $i->total());
    }
}

$i = new Invoice('INV-1', 12500);
echo (new InvoiceRenderer())->toText($i), PHP_EOL;

SRP: Mengenali Tanda Masalah

Pelanggaran SRP yang klasik adalah kelas yang namanya mengandung kata dan atau sebuah Manager yang melakukan segalanya. Perhatikan metode yang berubah karena alasan bisnis yang tidak berkaitan. Jika perubahan aturan pajak dan perubahan tata letak PDF sama-sama menyentuh kelas yang sama, kelas itu memiliki terlalu banyak tanggung jawab.

Prinsip Terbuka/Tertutup

Entitas perangkat lunak harus terbuka untuk perluasan dan tertutup untuk modifikasi. Menambahkan jenis potongan harga baru seharusnya tidak memaksa Anda mengubah switch besar. Gunakan polimorfisme: setiap aturan memiliki kelasnya sendiri yang menerapkan antarmuka bersama.

<?php
interface Discount { public function apply(float $total): float; }

final class PercentOff implements Discount {
    public function __construct(private float $pct) {}
    public function apply(float $t): float { return $t * (1 - $this->pct / 100); }
}
final class FlatOff implements Discount {
    public function __construct(private float $amount) {}
    public function apply(float $t): float { return max(0, $t - $this->amount); }
}

function checkout(float $total, Discount ...$discounts): float {
    foreach ($discounts as $d) { $total = $d->apply($total); }
    return $total;
}
echo checkout(100, new PercentOff(10), new FlatOff(5)), PHP_EOL; // 85

Substitusi Liskov

Subtipe harus dapat digunakan di mana pun tipe dasarnya diharapkan, tanpa mengejutkan pemanggil. Contoh terkenalnya: Square extends Rectangle melanggar LSP karena pengaturan lebar tidak boleh diam-diam mengubah tinggi. Sebaiknya modelkan keduanya sebagai tipe terpisah di balik antarmuka Shape yang sama.

<?php
interface Shape { public function area(): float; }

final class Rectangle implements Shape {
    public function __construct(private float $w, private float $h) {}
    public function area(): float { return $this->w * $this->h; }
}
final class Square implements Shape {
    public function __construct(private float $side) {}
    public function area(): float { return $this->side ** 2; }
}

$shapes = [new Rectangle(2, 3), new Square(4)];
foreach ($shapes as $s) { echo $s->area(), PHP_EOL; }

LSP dan Kontrak

LSP juga membatasi kontrak metode. Subtipe boleh melonggarkan prasyarat dan memperkuat pascakondisi, tetapi tidak boleh melakukan kebalikannya. Melempar jenis pengecualian baru yang tidak pernah dideklarasikan oleh tipe dasar, atau mengembalikan null ketika tipe dasar menjamin sebuah objek, melanggar substitutabilitas. Tipe nilai kembalian kovarian dan tipe parameter kontravarian PHP menegakkan sebagian aturan ini pada tingkat tipe.

Pemisahan Antarmuka

Klien seharusnya tidak bergantung pada metode yang tidak digunakannya. Antarmuka Worker yang terlalu besar, dengan work() dan eat(), memaksa RobotWorker membuat implementasi kosong untuk eat(). Pisahkan antarmuka berdasarkan peran agar setiap pelaksana hanya berkomitmen pada hal-hal yang benar-benar dilakukannya.

<?php
interface Workable { public function work(): string; }
interface Feedable { public function eat(): string; }

final class Human implements Workable, Feedable {
    public function work(): string { return 'coding'; }
    public function eat(): string { return 'lunch'; }
}
final class Robot implements Workable {
    public function work(): string { return 'welding'; }
}

foreach ([new Human(), new Robot()] as $w) { echo $w->work(), PHP_EOL; }

Pembalikan Dependensi

Kebijakan tingkat tinggi harus bergantung pada abstraksi, bukan detail konkret. Masukkan sebuah antarmuka, bukan kelas yang ditulis secara langsung. Dengan demikian, Anda dapat mengganti pengirim surel nyata dengan pengganti palsu dalam pengujian dan dengan vendor lain dalam produksi tanpa menyentuh pengguna layanan tersebut.

<?php
interface Mailer { public function send(string $to, string $body): void; }

final class SmtpMailer implements Mailer {
    public function send(string $to, string $body): void {
        echo "SMTP -> $to: $body" . PHP_EOL;
    }
}

final class SignupService {
    public function __construct(private Mailer $mailer) {}
    public function register(string $email): void {
        $this->mailer->send($email, 'Welcome!');
    }
}

(new SignupService(new SmtpMailer()))->register('a@b.com');

DIP dan Wadah

Pembalikan dependensi adalah prinsipnya; injeksi dependensi adalah salah satu teknik untuk memenuhinya. Wadah DI (PSR-11) menghubungkan SmtpMailer konkret ke abstraksi Mailer pada akar komposisi. Pengguna layanan tidak pernah menulis new SmtpMailer(), sehingga arah dependensi kode sumber mengarah ke abstraksi, bukan ke detail.

<?php
// Composition root wiring (pseudo-container)
$bindings = [
    Mailer::class => fn() => new SmtpMailer(),
];
$resolve = fn(string $id) => $bindings[$id]();

$service = new SignupService($resolve(Mailer::class));
$service->register('user@example.com');

SOLID secara Bersamaan

Prinsip-prinsip ini saling memperkuat. ISP menjaga antarmuka tetap kecil agar injeksi DIP tetap terarah; OCP bergantung pada polimorfisme yang dijaga keamanannya oleh LSP; SRP memberi Anda kelas-kelas kecil yang memungkinkan semua hal ini. Usahakan kohesi di dalam dan keterikatan longgar antarbagian.

  • Jangan membuat abstraksi berlebihan untuk kelas yang hanya digunakan sekali.
  • Perkenalkan antarmuka ketika implementasi kedua atau pengganti pengujian mulai diperlukan.

Pragmatisme

SOLID adalah sarana, bukan tujuan. Antarmuka yang dibuat terlalu dini dengan satu implementasi hanya menambah lapisan tidak langsung tanpa manfaat ("generalisasi spekulatif"). Terapkan prinsip-prinsip ini ketika perubahan benar-benar muncul atau jelas akan segera terjadi. Refaktor menuju SOLID menjadi mudah setelah Anda memiliki pengujian; melakukan refaktor secara membabi buta ke arah SOLID sejak hari pertama adalah pemborosan.

Pemeriksaan Singkat

Prinsip mana yang dilanggar oleh masalah pewarisan Square/Rectangle?

Rangkuman

Anda telah menerapkan kelima prinsip SOLID pada PHP nyata:

  • SRP: satu alasan untuk berubah pada setiap kelas.
  • OCP: perluas melalui kelas polimorfik baru, bukan dengan mengubah percabangan.
  • LSP: subtipe mematuhi kontrak tipe dasar.
  • ISP: gunakan antarmuka peran yang kecil, bukan antarmuka besar.
  • DIP: bergantung pada abstraksi dan masukkan detail di akar komposisi.

Gunakan prinsip-prinsip ini untuk memandu refaktor, bukan sebagai formalitas.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Prinsip SOLID dalam Praktik” gratis?

Ya — teks lengkap “Prinsip SOLID dalam Praktik” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus PHP Academy, upgrade ke CoddyKit PRO. Kursus PHP Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Prinsip SOLID dalam Praktik”?

Terapkan lima prinsip SOLID pada kelas PHP nyata. Kamu berlatih PHP Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai PHP Academy?

Tidak diperlukan pengalaman sebelumnya. PHP Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Prinsip SOLID dalam Praktik” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran PHP Academy ini?

Ya. Setiap pelajaran PHP Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Prinsip SOLID dalam Praktik
  2. Pola Pembuatan: Factory, Builder, Singleton
  3. Pola Struktural: Adapter, Decorator, Facade
  4. Pola Perilaku: Strategy, Observer, Command
← Kembali ke PHP Academy