Menu
CoddyTech

Pola Repository

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Dart di Coddy. Pelajaran 100 dari 110.

Pola Repository memisahkan logika akses data dari logika bisnis dengan membuat lapisan abstraksi antara aplikasi dan sumber data. Alih-alih membuat class-mu berinteraksi langsung dengan database, API, atau file, class-mu bekerja dengan repository yang menangani semua operasi data.

Pola ini mendefinisikan antarmuka untuk operasi data, dan implementasi konkret menangani mekanisme penyimpanan yang sebenarnya. Dengan demikian, kamu dapat mengganti sumber data dengan mudah tanpa mengubah logika bisnis:

// Entitas
class User {
  final int id;
  final String name;
  User(this.id, this.name);
}

// Antarmuka repositori
abstract class UserRepository {
  User? getById(int id);
  List<User> getAll();
  void save(User user);
  void delete(int id);
}

// Implementasi dalam memori
class InMemoryUserRepository implements UserRepository {
  final Map<int, User> _users = {};

  @override
  User? getById(int id) => _users[id];

  @override
  List<User> getAll() => _users.values.toList();

  @override
  void save(User user) => _users[user.id] = user;

  @override
  void delete(int id) => _users.remove(id);
}

void main() {
  UserRepository repo = InMemoryUserRepository();
  
  repo.save(User(1, 'Alice'));
  repo.save(User(2, 'Bob'));
  
  print(repo.getById(1)?.name);  // Alice
  print(repo.getAll().length);    // 2
}

Logika bisnis kamu hanya bergantung pada antarmuka UserRepository. Nanti, kamu bisa membuat DatabaseUserRepository atau ApiUserRepository yang mengimplementasikan antarmuka yang sama, lalu mengganti implementasinya tanpa mengubah kode apa pun yang menggunakan repository tersebut. Pola ini penting untuk aplikasi yang dapat diuji dan dipelihara, yang sumber datanya mungkin berubah seiring waktu.

challenge icon

Tantangan

Mudah

Mari kita buat sistem inventaris produk menggunakan pola Repository! Kamu akan membuat lapisan abstraksi yang memisahkan cara produk disimpan dari cara produk digunakan, sehingga implementasi penyimpanan dapat diganti dengan mudah tanpa mengubah logika bisnis.

Kamu akan mengatur kodemu dalam dua file:

  • product_repository.dart: File ini berisi entity dan class repository. Mulailah dengan class Product yang memiliki field final untuk id (int), name (String), dan price (double). Lalu, definisikan abstract class ProductRepository yang menyatakan kontrak untuk operasi data: getById(int id) yang mengembalikan Product nullable, getAll() yang mengembalikan list produk, save(Product product) untuk menyimpan produk, dan delete(int id) untuk menghapus produk. Terakhir, buat InMemoryProductRepository yang mengimplementasikan interface ini menggunakan Map<int, Product> untuk penyimpanan.
  • main.dart: Impor file repository-mu dan tunjukkan pola Repository saat digunakan. Buat InMemoryProductRepository, tetapi simpan dalam variabel bertipe ProductRepository. Ini menunjukkan bahwa kodemu bergantung pada interface, bukan implementasinya. Simpan tiga produk: Laptop (id: 1, price: 999.99), Mouse (id: 2, price: 29.99), dan Keyboard (id: 3, price: 79.99). Lalu, ambil dan cetak produk dengan id 2 dalam format Found: [name] - $[price]. Hapus produk dengan id 1. Terakhir, cetak jumlah produk yang tersisa dengan format Products in stock: [count].

Keunggulan pola ini adalah kode utamamu hanya mengenal interface ProductRepository. Nantinya, kamu bisa membuat DatabaseProductRepository atau ApiProductRepository, lalu menggantinya tanpa mengubah logika bisnis apa pun!

Output yang diharapkan:

Found: Mouse - $29.99
Products in stock: 2

Coba sendiri

import 'product_repository.dart';

void main() {
  // Buat repository. Perhatikan bahwa tipenya adalah interface, bukan implementasinya
  // TODO: Buat InMemoryProductRepository dan simpan dalam variabel ProductRepository
  
  // TODO: Simpan tiga produk:
  // - Laptop (id: 1, harga: 999.99)
  // - Mouse (id: 2, harga: 29.99)
  // - Keyboard (id: 3, harga: 79.99)
  
  // TODO: Ambil produk dengan id 2 dan cetak: "Found: [name] - $[price]"
  
  // TODO: Hapus produk dengan id 1
  
  // TODO: Cetak jumlah produk yang tersisa: "Products in stock: [count]"
}
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 Dart online