Menu
CoddyTech

Pola Repository

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 81 dari 91.

Repository Pattern adalah pola desain yang menjadi perantara antara logika bisnis aplikasi dan penyimpanan data. Pola ini menyediakan antarmuka seperti koleksi untuk mengakses object domain, sekaligus menyembunyikan detail tentang cara data sebenarnya disimpan atau diambil.

Anggap repository sebagai kumpulan khusus yang tahu cara menyimpan dan mengambil object. Kodemu meminta repository untuk mencari pengguna berdasarkan ID atau menyimpan produk baru, tanpa mengetahui apakah data disimpan di database, file, atau API. Pemisahan ini membuat kodemu lebih mudah diuji dan fleksibel.

<?php
interface UserRepositoryInterface {
    public function find(int $id): ?User;
    public function findAll(): array;
    public function save(User $user): void;
    public function delete(int $id): void;
}

class User {
    public function __construct(
        public int $id,
        public string $name,
        public string $email
    ) {}
}

Implementasi repository menangani mekanisme penyimpanan yang sebenarnya:

<?php
class InMemoryUserRepository implements UserRepositoryInterface {
    private array $users = [];
    
    public function find(int $id): ?User {
        return $this->users[$id] ?? null;
    }
    
    public function findAll(): array {
        return array_values($this->users);
    }
    
    public function save(User $user): void {
        $this->users[$user->id] = $user;
    }
    
    public function delete(int $id): void {
        unset($this->users[$id]);
    }
}

$repo = new InMemoryUserRepository();
$repo->save(new User(1, "Alice", "alice@example.com"));
$repo->save(new User(2, "Bob", "bob@example.com"));

echo $repo->find(1)->name . "\n";
echo count($repo->findAll());

Keluaran:

Alice
2

Keunggulan pola ini adalah kamu dapat mengganti implementasi tanpa mengubah logika bisnismu. Perlu beralih dari penyimpanan di memori ke database? Buat class repository baru yang mengimplementasikan interface yang sama. Kode aplikasimu tetap tidak berubah karena bergantung pada interface, bukan implementasi konkretnya.

challenge icon

Tantangan

Mudah

Mari bangun sistem inventaris produk menggunakan Repository Pattern. Kamu akan membuat pemisahan yang jelas antara object domain dan cara penyimpanannya, sehingga kode aplikasimu dapat bekerja dengan produk tanpa mengetahui detail penyimpanannya.

Kamu akan mengatur kodemu dalam empat file:

  • Product.php: Buat class Product yang mewakili item dalam inventarismu. Setiap produk memiliki id (int), name (string), dan price (float). Gunakan promosi konstruktor dengan property publik agar mudah diakses.
  • ProductRepositoryInterface.php: Definisikan ProductRepositoryInterface yang menetapkan kontrak untuk setiap implementasi penyimpanan produk. Interface-mu harus mendeklarasikan method berikut:
    • find(int $id): ?Product: Ambil produk berdasarkan ID, atau null jika tidak ditemukan
    • findAll(): array: Dapatkan semua produk sebagai array
    • save(Product $product): void: Simpan atau perbarui produk
    • delete(int $id): void: Hapus produk berdasarkan ID
  • InMemoryProductRepository.php: Sertakan class Product dan interface. Buat class InMemoryProductRepository yang mengimplementasikan interface menggunakan array privat untuk menyimpan produk. Produk harus diindeks berdasarkan ID-nya agar pencarian efisien. Method findAll() harus mengembalikan object produk saja (gunakan array_values() untuk mengatur ulang kunci array).
  • main.php: Sertakan file repository. Kamu akan menerima dua input: pertama string JSON berisi produk yang akan ditambahkan, lalu pada baris terpisah, ID integer yang akan dicari.

    Format JSON-nya:

    [{"id": 1, "name": "Laptop", "price": 999.99}, {"id": 2, "name": "Mouse", "price": 29.99}]

    Buat InMemoryProductRepository, simpan semua produk dari input JSON, lalu gunakan input kedua (ID) untuk mencari produk tertentu. Cetak hasilnya dengan format berikut:

    Total products: [count]
    Found: [name] - $[price]

    Format harga dengan dua angka di belakang koma. Jika produk tidak ditemukan, cetak Found: Not found.

Repository Pattern sangat berguna saat kamu perlu mengganti implementasi penyimpanan. Kode utamamu hanya bergantung pada interface: beralih dari penyimpanan dalam memori ke database berarti membuat class repository baru tanpa mengubah logika aplikasi apa pun.

Coba sendiri

<?php

require_once 'InMemoryProductRepository.php';

// Baca input
$jsonInput = trim(fgets(STDIN));
$searchId = intval(trim(fgets(STDIN)));

// Ubah input JSON menjadi array
$productsData = (array)json_decode($jsonInput, true);

// TODO: Buat instance InMemoryProductRepository

// TODO: Telusuri $productsData dan simpan setiap produk
// Setiap item memiliki kunci 'id', 'name', dan 'price'

// TODO: Ambil semua produk dan cetak jumlah totalnya
// Format: "Total products: [count]"

// TODO: Cari produk dengan $searchId
// Jika ditemukan, cetak: "Found: [name] - $[price]" (format price menjadi 2 angka di belakang koma)
// Jika tidak ditemukan, cetak: "Found: Not found"

?>
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler PHP online