Bagian 12. Penjumlahan

Pada bagian 11 kita telah menyelesaikan class Money dan juga telah menghapus kedua turunannya serta melakukan kegiatan bersih-bersih di class MoneyFixture. Todo list kita sekarang sudah penuh dengan tulisan dan coretan. Ambil kertas baru dan pindahkan yang tersisa.

$5 + Rp 10=Rp 9.010 jika $1=Rp 9000

Pembulatan uang?

GetHashCode()

Jenis object?

Null?

Mana yang akan kita kerjakan terlebih dahulu? Pembulatan, belum pasti. Hashcode, null dan jenis object erat kaitannya dengan equality yang saya pikir untuk sementara cukup disini dulu. Keempat case ini kita simpan dulu di laci. Sehingga dari list itu kita tinggal punya satu case,

$5 + Rp 10=Rp 9.010 jika $1=Rp 9000

Saya tidak tahu dari mana kita akan memulainya. Penjumlahan ini sudah agak kompleks, kita harus melakukan konversi dolar ke Rupiah baru kemudian bisa menjumlahkan. Siapa yang berhak melakukan konversi. Darimana kita mendapatkan rate Rupiah vs Dollar. Belum lagi siapa yang berhak mengeluarkan rate.

Satu hal yang sudah pasti: kita harus bisa menjumlahkan dua buah object uang yang mempunyai currency sama. Jadi kita harus bisa menjumlahkan Rupiah dengan Rupiah terlebih dahulu sebelum melakukannya dengan Dollar. Bagaimana kalau kita coba menjumlahkan Rp 10 + Rp 10=Rp 20.

$5 + Rp 10=Rp 9.010 jika $1=Rp 9000

Rp 10 + Rp 10=Rp 20

Test yang bisa kita buat dari pernyataan ini adalah sebagai berikut,

[Test]
public void SimpleAddition(){
	Money sum=Money.Rp(10).Plus(Money.Rp(10));
	Assert.AreEqual(Money.Rp(20),sum);
}

Kita belum memiliki method Plus di class Money. Ada dua cara implementasi method Plus, pertama implementasi bohongan (fake) yaitu dengan me-return Money.Rp(20) atau dengan cara kedua yaitu dengan implementasi langsung. Cara kedua kelihatannya lebih tepat untuk kasus kita ini. Implementasinya cukup jelas yaitu cukup dengan menjumlahkan kedua amount dan memberinya currency rupiah.

public  class Money{
	...
	public Money Plus(Money addend){
		return new Money(this.m_amount + addend.m_amount,this.m_currency);
	}
}

Seperti yang sudah kita duga, impelementasi yang cukup jelas ini langsung memenuhi test yang kita harapkan, green.

Selesai? Belum, jangan senang dulu, implementasi diatas belum bisa menyelesaikan case multi currency. Tetapi paling tidak kita telah memiliki satu modal: menjumlahkan uang yang currency-nya sama.

Salah satu cara yang mungkin bisa kita gunakan adalah dengan mengkonversi semua bentukk uang ke salah satu matauang, katakanlah USD. Sayangnya cara ini tidak memnungkinkan karena rate matauang selalu berubah-ubah.

Cara yang lain adalah dengan mencari kiasan (metaphor) atau analogi yang berkaitan dengan kasus kita ini. Misalnya, dompet. Kita semua bisa dipastikan mempunyai dompet. Di dalamnya bisa berisi banyak uang, bisa dua atau lebih matauang. Sayangnya dompet hanya bisa mengatakan berapa duit dalam matauang tertentu. Tentu ini bukan kiasan yang tepat.

Kiasan yang lain adalah ekspresi. 2+3*5 adalah salah satu bentuk ekspresi. Dalam kasus kita, (Rp2 +i$3)*5 adalah ekspersi. $5 + Rp 10 juga salah satu bentuk ekspresi. Hasil dari ekspresi ini bisa dikembalikan kesalah satu bentuk matauang.

Dengan kiasan ini kita bisa mengubah test kita menjadi,

[Test]
public void SimpleAddition(){
	...
	Assert.AreEqual(Money.Rp(20),hasilTukar);
}

Variabel hasilTukar adalah hasil setelah ditukar oleh sistem lain, katakanlah money changer atau mungkin bank.

[Test]
public void SimpleAddition(){
	...
	Money hasilTukar=bank.Tukar(sum,"Rp");
	Assert.AreEqual(Money.Rp(20),hasilTukar);
}

Dan bank kita definisikan,

[Test]
public void SimpleAddition(){
	...
	Bank bank=new Bank();
	Money hasilTukar=bank.Tukar(sum,"Rp");
	Assert.AreEqual(Money.Rp(20),hasilTukar);
}

Kemudian variabel sum? Nah inilah ekspersi kita. Jadi bank menerima ekspresi kita baru dia konvert sesuai keinginan.

[Test]
public void SimpleAddition(){
	...
	Ekspression sum=sepuluhRupiah.Plus(sepuluhRupiah);
	Bank bank=new Bank();
	Money hasilTukar=bank.Tukar(sum,"Rp");
	Assert.AreEqual(Money.Rp(20),hasilTukar);
}

Darimana datangnya sepuluhRupiah? Mudah ditebak.

[Test]
public void SimpleAddition(){
	Money sepuluhRupiah=Money.Rp(10);
	Ekspression sum=sepuluhRupiah.Plus(sepuluhRupiah);
	Bank bank=new Bank();
	Money hasilTukar=bank.Tukar(sum,"Rp");
	Assert.AreEqual(Money.Rp(20),hasilTukar);
}

Kenapa mesti ada 2 kiasan disini, bank dan ekspresi? Apakah tidak langsung saja hasil nilai tukar adalah keluaran dari ekspresi? Ada 2 alasan:
Ekspresi biarlah tetap apa adanya ekspresi. Biarlah ungkapan tetap ungkapan. Ekspresi kesedihan biarlah tetap seperti itu. Tidak perlu ada hasil yang bisa dinyatakan.
Jika ekspresi itu ada hasil, akan banyak sekali hasil yang melekat padanya. Kali, bagi, jumlah dan lain-lain yang kita tidak bisa membatasinya. Kenapa lantas kita pilih bank? Karena dialah yang terlintas pertama kali pada saat memikirkan siapa yang berhak menukar.

Bagaimana jika kiasan-kiasan seperti diatas tidak lekas muncul padahal TDD menuntut kita bertindak cepat? Karena itulah kita melakukan TDD. Dengan TDD semua code yang kita tulis selalu tertest, sehingga kita tidak perlu merasa khawatir kalau kita sering membuat perubahan. Jadi ketika secercah petunjuk itu datang, kita bisa segera membuat tindakan tanpa perlu khawatir.

Langkah berikutnya: bagaimana agar test kita berjalan (bisa dicompile). Pertama kita harus membuat class Ekspression. Tetapi rasanya class terlalu berat, bagaimana kalau interface saja, jadi kita ubah menjari IEkpression. Sehingga test kita juga berubah,

[Test]
public void SimpleAddition(){
	Money sepuluhRupiah=Money.Rp(10);
	IEkspression sum=sepuluhRupiah.Plus(sepuluhRupiah);
	Bank bank=new Bank();
	Money hasilTukar=bank.Tukar(sum,"Rp");
	Assert.AreEqual(Money.Rp(20),hasilTukar);
}

Dan ini adalah interface kita,

public interface IEkspression{ 

}

Siapa yang akan mengimplemantasikan IEkspression? Tentu saja class Money dan output dari method Plus harus kita ubah kebentuk IEkspression,

public  class Money:IEkspression{
		...
		public IEkspression Plus(Money addend){
			return new Money(this.m_amount + addend.m_amount,this.m_currency);
		}
	}

Berikutnya kita juga harus membuat class Bank yang mempunyai method Tukar(),

public class Bank{
	public Money Tukar(IEkspression ekpspresi, string tukarKe){
		return null;
	}
}

Nah, sekarang bisa kita kompile. Dan tentu saja RED. Tidak apa-apa, ini juga salah satu bentuk progress.

Untuk membuat test kita GREEN, kita cukup membohonginya dengan mereturn Rp20,

public class Bank{
	public Money Tukar(IEkspression ekpspresi, string tukarKe){
		return Money.Rp(20);
	}
}

Kita telah melakukan “make it run”. Kini saatnya merefaktor agar menjadi “right”.

Iklan

There are no comments on this post.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: