Port dan Adapter Dijelaskan
Pisahkan inti dengan port dan adapter yang dapat dipasang.
Port dan Adapter Dijelaskan adalah pelajaran PHP Academy gratis di CoddyKit. Ini adalah pelajaran 2 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.
Gagasan Heksagon
Port & Adaptor — Arsitektur Heksagonal karya Alistair Cockburn — menggambarkan aplikasi Anda sebagai sebuah heksagon. Di dalamnya terdapat logika bisnis murni. Setiap interaksi dengan dunia luar (HTTP, basis data, antrean, jam, email) melewati sebuah port, dan setiap port dipenuhi oleh satu atau beberapa adaptor. Bentuk ini tidak mengistimewakan sisi atas atau bawah: antarmuka pengguna dan basis data bersifat simetris, keduanya hanyalah adaptor.
Port adalah Antarmuka
Sebuah port adalah antarmuka yang dimiliki inti aplikasi dan menyatakan kebutuhan atau kapabilitas dalam istilah domain. Port tidak boleh membocorkan kosakata infrastruktur — tidak boleh ada PDOStatement, GuzzleResponse, atau Eloquent.
<?php
// Driven (outbound) port: the core needs to persist users
interface UserRepository
{
public function byId(UserId $id): ?User;
public function save(User $user): void;
}Port Penggerak vs Port yang Digerakkan
Ada dua jenis:
- Port penggerak (utama, masuk) — API yang dipanggil dunia luar untuk menggerakkan aplikasi. Biasanya berupa antarmuka kasus penggunaan.
- Port yang digerakkan (sekunder, keluar) — antarmuka yang dipanggil aplikasi untuk menjangkau dunia luar: repositori, pengirim email, dan jam.
Adaptor penggerak memanggil inti; inti memanggil keluar melalui adaptor yang digerakkan.
<?php
// Driving (inbound) port — the public capability of the core
interface RegisterUser
{
public function handle(string $email, string $plainPassword): UserId;
}Inti Mengimplementasikan Port Penggerak
Kasus penggunaan mengimplementasikan port penggerak dan bergantung pada port yang digerakkan. Perhatikan bahwa kasus ini menerima PasswordHasher dan Clock sebagai port yang disuntikkan — bahkan waktu dan pembuatan hash dibuat abstrak agar inti tetap deterministik dan dapat diuji.
<?php
final class RegisterUserService implements RegisterUser
{
public function __construct(
private UserRepository $users,
private PasswordHasher $hasher,
private Clock $clock,
) {}
public function handle(string $email, string $plain): UserId {
if ($this->users->byEmail($email)) {
throw new EmailAlreadyTaken($email);
}
$user = User::register(
$email,
$this->hasher->hash($plain),
$this->clock->now()
);
$this->users->save($user);
return $user->id();
}
}Adaptor yang Digerakkan
Sebuah adaptor yang digerakkan mengimplementasikan port yang digerakkan menggunakan teknologi konkret. Di sini, adaptor PDO memenuhi UserRepository. Tukarkan adaptor tersebut dengan Doctrine, Redis, atau klien API HTTP tanpa menyentuh inti.
<?php
final class PdoUserRepository implements UserRepository
{
public function __construct(private PDO $pdo) {}
public function byId(UserId $id): ?User {
$stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([(string) $id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? User::fromRow($row) : null;
}
public function save(User $user): void {
// INSERT ... ON CONFLICT UPDATE
}
}Adaptor Penggerak
Sebuah adaptor penggerak menerjemahkan pemicu eksternal menjadi pemanggilan pada port penggerak. Pengontrol HTTP, perintah CLI, atau konsumen pesan — semuanya merupakan adaptor penggerak yang dapat dipertukarkan untuk kasus penggunaan yang sama.
<?php
// CLI driving adapter
final class RegisterUserCommand
{
public function __construct(private RegisterUser $register) {}
public function run(array $argv): int {
[$email, $password] = array_slice($argv, 1);
$id = $this->register->handle($email, $password);
fwrite(STDOUT, "Created user $id\n");
return 0;
}
}Adaptor Dalam Memori untuk Pengujian
Manfaat terbesarnya: setiap port yang digerakkan mendapatkan tiruan cepat. Pengujian menjalankan kasus penggunaan sesungguhnya terhadap adaptor dalam memori, jam deterministik, dan pembuat hash tanpa operasi.
<?php
final class FixedClock implements Clock {
public function __construct(private DateTimeImmutable $t) {}
public function now(): DateTimeImmutable { return $this->t; }
}
final class PlainHasher implements PasswordHasher {
public function hash(string $p): string { return 'h:' . $p; }
}
$service = new RegisterUserService(
new InMemoryUsers(),
new PlainHasher(),
new FixedClock(new DateTimeImmutable('2026-01-01'))
);
echo 'wired OK', PHP_EOL;Adaptor Menerjemahkan, Bukan Mengambil Keputusan
Kesalahan umum adalah membiarkan aturan bisnis merembes ke adaptor. Patokan praktisnya: adaptor hanya menerjemahkan format data dan protokol. Jika Anda menemukan if tentang penetapan harga, kelayakan, atau status di dalam pengendali atau repositori, aturan itu seharusnya berada di inti.
- Pemetaan JSON ↔ objek transfer data: adaptor
- SQL ↔ pengisian entitas: adaptor
- "VIP mendapat potongan 10%": inti
Satu Port, Banyak Adaptor
Port memungkinkan substitusi dan bahkan adaptor paralel. Sebuah NotificationPort dapat memiliki adaptor Email, SMS, dan Slack yang dirangkai bersama. Inti menjalankan satu metode; perangkaian menentukan berapa banyak saluran yang merespons.
<?php
interface Notifier { public function send(string $to, string $msg): void; }
final class CompositeNotifier implements Notifier {
/** @param Notifier[] $channels */
public function __construct(private array $channels) {}
public function send(string $to, string $msg): void {
foreach ($this->channels as $c) $c->send($to, $msg);
}
}
$notifier = new CompositeNotifier([new EmailNotifier(), new SmsNotifier()]);
echo 'composed', PHP_EOL;Pemetaan Segi Enam ke Folder
Tata letak PHP yang praktis untuk konteks terbatas:
Domain/— entitas, objek nilai, layanan domainApplication/Port/In/— antarmuka port penggerak (kasus penggunaan)Application/Port/Out/— antarmuka port yang digerakkan (repositori, jam)Application/— implementasi kasus penggunaanInfrastructure/Adapter/In/— pengendali, CLI, konsumenInfrastructure/Adapter/Out/— adaptor PDO/Doctrine/HTTP
Akar komposisi (konfigurasi wadah DI) merangkai adaptor In dan Out ke port.
Menguji Seluruh Segi Enam
Selain pengujian unit, port memungkinkan pengujian penerimaan yang cepat dengan menjalankan aplikasi melalui port utamanya dan melakukan verifikasi melalui adaptor sekunder dalam memori — mencakup satu kasus penggunaan lengkap tanpa HTTP atau basis data. Rangkaian pengujian yang sama nantinya dapat dijalankan terhadap adaptor nyata sebagai pengujian integrasi, sehingga memberi Anda strategi pengujian berlapis tanpa penulisan ulang.
<?php
// Acceptance test: real use case, fake driven adapters, no I/O
$users = new InMemoryUsers();
$service = new RegisterUserService($users, new PlainHasher(),
new FixedClock(new DateTimeImmutable('2026-01-01')));
$id = $service->handle('dev@coddykit.com', 'pw');
assert($users->byId($id) !== null);
echo 'acceptance: user persisted via in-memory adapter', PHP_EOL;Pemeriksaan Singkat
Pernyataan manakah tentang port dan adaptor yang benar?
Ringkasan
Port & Adaptor mengisolasi inti di balik antarmuka:
- Port adalah antarmuka yang menggunakan istilah domain dan dimiliki oleh inti.
- Port penggerak dipanggil oleh adaptor masuk; port yang digerakkan dipanggil oleh inti dan dipenuhi oleh adaptor keluar.
- Adaptor hanya menerjemahkan protokol dan format — tidak pernah mengambil keputusan bisnis.
- Port yang sama mendukung banyak adaptor (tiruan untuk pengujian, komposit untuk pengiriman ke banyak tujuan).
- Akar komposisi merangkai semuanya; segi enam tetap bebas dari kerangka kerja.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Port dan Adapter Dijelaskan” gratis?
Ya — teks lengkap “Port dan Adapter Dijelaskan” 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 “Port dan Adapter Dijelaskan”?
Pisahkan inti dengan port dan adapter yang dapat dipasang. 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 2 dari 4.
Berapa lama pelajaran “Port dan Adapter Dijelaskan” 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
- Dari Arsitektur Berlapis ke Arsitektur Bersih
- Port dan Adapter Dijelaskan
- Kasus Penggunaan dan Layanan Aplikasi
- Inversi Dependensi dalam Praktik