Bagian 9. Mata Uang

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

Rp 10 * 2 = Rp 20

Efek perkalian terhadap object?

Amount harus private?

Pembulatan uang?

Equals()

GetHashCode()

Jenis object?

Null?

$10*2=$20

Duplikasi dolar dan rupiah

Equality yang lebih umum

Method Times() yang lebih umum

Bedakan dollar dan rupiah

Currency?

Hapus test DollarMultiplication

Di bagian 8 kita telah memakai tipe class untuk membandingkan dua object. Nah, ingat kan. Memasukkan tipe class ke dalam domain/model kita adalah tidak benar. Kita harus mencari cara agar tipe class ini tidak kita pakai. Bagaimana kalau kita coba memakai mata uang?

Ok. Bagaimana cara mengimplementasikannya? Loh, bukannya harus dari test dulu. Betul. Pertanyaannya harus diganti, “bagaimana caranya melakukan test terhadap mata uang?”

Kita coba memakai pattern flyweight factory agar object yang ter-create hanya yang kita butuhkan saja,

[Test]
public void Currency(){
	Assert.AreEqual("Rp",Money.Rp(1).Currency);
	Assert.AreEqual("US",Money.US(1).Currency);
}

Agar bisa dikompile kita harus mendeklarasikan property Currency di class Money

public abstract class Money{
	...
	public abstract string Currency {get;}
}

dan masing-masing class Rupiah dan Dollar harus mengimplementasikan property ini

public class Dollar:Money{
	...
	public override string Currency {
		get {
			return "";
		}
	}
}

public class Rupiah:Money{
	...
	public override string Currency {
		get {
			return "";
		}
	}
}

Dengan implementasi seperti ini kita bisa mengkompile program dan menjalankan test. Tentu saja baru tahap make it run. Hasil test masih gagal, tetapi ditempat yang tepat yaitu dibagian yang mengatakan bahwa yang dibutuhkan “Rp” tetapi yang muncul malah “”.

Selanjutnya kita melakukan tahap berikutnya, make it run. Agar test berjalan dan berhasil, seperti petunjuk Kent, kita bisa memberi implementasi boongan (fake it) atau implementasi sungguhan tetapi berupa langkah kecil. Ok, kita akan coba langkah kedua.

Kapan seharusnya currency itu ada? Pada saat uang dibikin bukan. Jadi konstruktornya kita ubah sedikit.

public class Rupiah:Money{
	private string m_currency;
	public Rupiah(int amount){
		this.m_amount=amount;
		this.m_currency="Rp";
	}
	public override string Currency {
		get {
			return this.m_currency;
		}
	}
}

dan untuk Dollar

public class Dollar:Money{
	private string m_currency;
	public Dollar(int amount){
		this.m_amount=amount;
		this.m_currency="US";
	}
	public override string Currency {
		get {
			return this.m_currency;
		}
	}
}

Jadi kita definisikan variabel m_currency untuk menghandle state dari mata uang, sedangkan mata uang-nya sendiri kita set lewat konstruktor. Nah, property Currency me-return nilai dari state m_currency.

Test saya jalankan. Hore…! Berhasil.

Selesai? Belum. Terdapat duplikasi m_currency yang harus kita hilangkan. Cara termudah adalah dengan menaikkan m_currency ke class Money.

public abstract class Money{
	protected string m_currency;
	...
}

Kemudian deklarasi m_currency di masing-masing class Dollar dan Rupiah harus kita hapus.

Test saya jalankan kembali dan masih OK.

Selesai? Belum. Rasanya kalau string “US” dan “Rp” kita supplay saja lewat konstruktor dan untuk membatasi pembuatan object lewat factory, maka kita akan lebih dekat pada misi menghapus duplikasi Rupiah dan Dollar. Ok. Kita coba dulu untuk Rupiah.

public class Rupiah:Money{
	public Rupiah(int amount, string currency){
		this.m_amount=amount;
		this.m_currency="Rp";
	}
	...
}

Kompiler memberitahu bahwa factory Rupiah juga harus diubah karena Rupiah tidak lagi menyediakan konstruktor tunggal.

public abstract class Money{
	...
	public static Money Rp(int amount){
		return new Rupiah(amount,null);
	}
	...
}

Sementara kita suplay dengan null. Kita kompile lagi. Duh, masih nyangkut juga. Kali ini tersangkut di method Times().

public class Rupiah:Money{
	...
	public override Money Times(int multiplier){
		return new Rupiah(this.m_amount *multiplier,null);
	}
	...
}

Tunggu sebentar. Mengapa kita tidak ubah saja konstruktor ini dengan yang ada di factory? Dengan diubah, menjadi pasti bahwa yang berhak membuat object ya cuma factory. Ok. Saya setuju. Tapi jangan sekarang. Mengapa? Kita harus tetap fokus pada persoalan utama kita. Sebab sebuah interupsi cukup membuat konsentrasi kita hilang, dan itu berarti bug, stress, serta sakit gigi.

Test saya jalankan dan …. Oh lega rasanya…berhasil.

Sekarang saatnya kita fokus pada mengganti konstruktor di method Times() dengan factory method.

public class Rupiah:Money{
	...
	public override Money Times(int multiplier){
		return Money.Rp(this.m_amount *multiplier);
	}
	...
}

Test saya jalankan lagi dan sukses.
Sekarang kita bisa mensuplay “Rp” melalui factory

public abstract class Money{
	...
	public static Money Rp(int amount){
		return new Rupiah(amount,"Rp");
	}
	...
}

Dan kosntruktor Rupiah berubah menjadi

public class Rupiah:Money{
	public Rupiah(int amount, string currency){
		this.m_amount=amount;
		this.m_currency=currency;
	}
	...
}

Test saya jalankan lagi dan sukses.

Nah sekarang bagaimana dengan Dollar? Apakah kita akan menggunakan lagi langkah-langkah keci? Membosankan! Percaya diri nih ye…Bagaimana tidak, Rupiah dengan Dollar kan sama saja. Sia-sia mengikuti jalan yang pernah kita lalui toh hasilnya sudah bisa diprediksi sama. Sudah…sudah jangan cerewet. Kalau memang PD yok kita ambil langkah seribu untuk Dollar. Contek saja yang Rupiah.

Pertama, factory method

public abstract class Money{
	....
	public static Money US(int amount){
		return new Dollar(amount,"US");
	}
	...
}

Kedua, konstruktor

public class Dollar:Money{
	public Dollar(int amount, string currency){
		this.m_amount=amount;
		this.m_currency=currency;
	}
	...
}

Ketiga, method Times()

public class Dollar:Money{
	...
	public override Money Times(int multiplier){
		return Money.US(this.m_amount *multiplier);
	}
	...
}

Test saya jalankan. Horee!! Langkah seribu yang hebat! Luar biasa. TDD adalah teknik mengendalikan proses, seperti mengendari mobil/motor. Tentukan tujuan, start mesin, belokkan sedikit, luruskan, belokkan sedikit, dan seterusnya, dan seterusnya. Sedikit demi sedikit. Tidak ada ukuran pasti berapa besarnya sedikit itu, sekarang dan selamanya.

Sekarang kedua kosntruktor sudah sama persis sehingga bisa kita letakkan saja di class Money.

public abstract class Money{
	...
	public Money(int amount, string currency){
		this.m_amount=amount;
		this.m_currency=currency;
	}
	...
}

dan konstruktor Rupiah

public class Rupiah:Money{
	public Rupiah(int amount, string currency):base(amount,currency){
	}
}

serta konstruktor Dollar

public class Dollar:Money{
	public Dollar(int amount, string currency):base(amount,currency){
	}
	...
}

Test saya jalankan. Tetap sukses.

Kita cukupkan sampai disini dulu, supaya bagian ini tidak panjang. Ingat tujuan kita, menghapus duplikasi Rupiah dan Dollar belum terwujud. Namun sekarang sudah semakin jelas. Jika kita bisa menyelesaikan method Times(). Maka kedua class ini bisa kita hapus. Dan itu sudah semakin dekat.

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

Rp 10 * 2 = Rp 20

Efek perkalian terhadap object?

Amount harus private?

Pembulatan uang?

Equals()

GetHashCode()

Jenis object?

Null?

$10*2=$20

Duplikasi dolar dan rupiah

Equality yang lebih umum

Method Times() yang lebih umum

Bedakan dollar dan rupiah

Currency?

Hapus test DollarMultiplication

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: