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 tersebut bekerja dengan repository yang menangani semua operasi data.

Pola ini menentukan antarmuka untuk operasi data, sedangkan implementasi konkret menangani mekanisme penyimpanan yang sebenarnya. Dengan begitu, kamu bisa mengganti sumber data dengan mudah tanpa mengubah logika bisnis:

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

// Antarmuka repository
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. Nantinya, kamu dapat membuat DatabaseUserRepository atau ApiUserRepository yang mengimplementasikan antarmuka yang sama, lalu mengganti implementasinya tanpa mengubah kode apa pun yang menggunakan repositori tersebut. Pola ini penting untuk aplikasi yang dapat diuji dan mudah dipelihara, terutama saat sumber data dapat berubah seiring waktu.

challenge icon

Tantangan

Mudah

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

Kamu akan mengatur kodemu ke dalam dua file:

  • product_repository.dart: File ini berisi entity dan class repository-mu. Mulailah dengan class Product yang memiliki field final untuk id (int), name (String), dan price (double). Lalu, definisikan class abstrak ProductRepository yang menyatakan kontrak untuk operasi data: getById(int id) yang mengembalikan Product yang bisa bernilai null, getAll() yang mengembalikan list produk, save(Product product) untuk menyimpan produk, dan delete(int id) untuk menghapus produk. Terakhir, buat InMemoryProductRepository yang mengimplementasikan antarmuka ini menggunakan Map<int, Product> sebagai penyimpanan.
  • main.dart: Impor file repository-mu dan tunjukkan pola Repository. Buat InMemoryProductRepository, tetapi simpan dalam variabel bertipe ProductRepository. Ini menunjukkan bahwa kodemu bergantung pada antarmuka, 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 sebagai Products in stock: [count].

Keunggulan pola ini adalah kode utamamu hanya mengenal antarmuka ProductRepository. Nantinya, kamu dapat membuat DatabaseProductRepository atau ApiProductRepository dan 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, price: 999.99)
  // - Mouse (id: 2, price: 29.99)
  // - Keyboard (id: 3, price: 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