Cascade Notation (..)
Merangkai banyak operasi pada satu objek tanpa variabel sementara.
Panggil beruntun tanpa repetisi
Mengatur objek sering butuh banyak panggilan beruntun: cat.warna = 'merah'; cat.mesin(); cat.jalan();. Menulis nama variabel berulang-ulang itu bising. Cascade notation (..) merangkai operasi pada objek yang sama dalam satu ekspresi.
Analogi: cascade itu seperti memberi banyak instruksi ke satu orang tanpa menyebut namanya tiap kali: "Budi, pakai helm. Budi, nyalakan motor. Budi, jalan." menjadi "Budi: pakai helm, nyalakan motor, jalan."
Kenapa cascade ada?
Untuk builder pattern dan konfigurasi objek: rangkai banyak setter/pemanggilan tanpa variabel sementara. Kode terlihat seperti "resep perakitan" yang mengalir.
Bentuk dasar
class Kopi {
String jenis = '';
bool gula = false;
bool susu = false;
void seduh() => print('Menyeduh $jenis...');
void sajikan() => print('Sajikan: $jenis, gula: $gula, susu: $susu');
}
void main() {
// Tanpa cascade: nama variabel diulang
var k1 = Kopi();
k1.jenis = 'tubruk';
k1.gula = true;
k1.seduh();
// Dengan cascade: satu alur
var k2 = Kopi()
..jenis = 'latte'
..gula = true
..susu = true
..seduh()
..sajikan();
}.. artinya "lakukan operasi ini pada objek yang sama, lalu kembalikan objeknya (bukan hasil operasi)". Karena yang dikembalikan tetap objeknya, rantai bisa berlanjut.
Contoh kedua, cascade pada list dan objek bawaan:
void main() {
// Membangun list bertahap
var angka = <int>[]
..add(1)
..add(2)
..addAll([3, 4])
..remove(2);
print(angka); // [1, 3, 4]
// StringBuffer: membangun string efisien
var sb = StringBuffer()
..write('Halo, ')
..write('Dunia')
..write('!');
print(sb.toString()); // Halo, Dunia!
}Tanpa cascade, add mengembalikan void sehingga tidak bisa dirangkai. Cascade mengabaikan return value dan selalu meneruskan objeknya.
?.. : cascade aman-null
class Mesin {
void nyalakan() => print('Mesin nyala');
}
void main() {
Mesin? m;
m?..nyalakan(); // aman: tidak jalan karena m null
m = Mesin();
m?..nyalakan(); // Mesin nyala
}?.. membatalkan seluruh rantai jika objeknya null. Kombinasi dengan null safety.
Kesalahan umum
1. Tertukar .. dengan .
void main() {
var sb = StringBuffer();
// var x = sb.write('a').write('b'); // ERROR: write() return void
sb
..write('a')
..write('b');
print(sb); // ab
}Satu titik (.) memakai return value method; dua titik (..) mengabaikannya dan meneruskan objek.
2. Cascade pada hasil yang ingin dipakai
void main() {
var list = <int>[]
..add(1)
..add(2);
// var x = list..length; // x adalah list, BUKAN 3!
var panjang = list.length; // BENAR: 2
print(panjang);
}Ingat: cascade selalu menghasilkan objeknya sendiri, bukan hasil operasi terakhir.
3. Cascade terlalu panjang
Rantai 15 operasi menjadi sulit dibaca dan di-debug (error di tengah rantai sulit dilacak barisnya). Batas wajar: 4-6 operasi. Lebih dari itu, pecah jadi beberapa statement.
Kesimpulan
.. merangkai operasi pada objek yang sama, ?.. versi aman-null. Ideal untuk konfigurasi builder dan perakitan bertahap. Ingat bedanya dengan . biasa.
Catatan teknis: Cascade juga bisa dipakai untuk assignment:
obj..x = 1..y = 2. Dan di Flutter, cascade sering dipakai untuk mengkonfigurasi controller:TextEditingController()..text = 'isi'.
Tantangan
Rakit query URL
Pakai StringBuffer + cascade untuk membangun query URL dari map {'q': 'dart', 'page': '2', 'sort': 'asc'} menjadi 'q=dart&page=2&sort=asc'. Tanpa cascade dilarang!
void main() {
var params = {'q': 'dart', 'page': '2', 'sort': 'asc'};
var sb = StringBuffer();
// TODO: cascade write '&' di antara pasangan, tanpa '&' di akhir
// Petunjuk: pakai entries.toList() + index
print(sb.toString());
}