Bagian 8. Class Make Over

$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?

Perhatikan dua class berikut ini:

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

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

	}

Kedua class memiliki method Times() yang sama persis modelnya kecuali pada bagian konstruksi objectnya dan output dari method ini. Untuk membuat keduanya agar lebih mendekati kesamaan, kita bisa ganti output menjadi Money.

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

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

	}

Test saya jalankan dan berjalan sukses.
Tujuan kita sebernarnya adalah untuk menghapus sub-class, karena Dollar dan Rupiah kenyataanya tidak jauh berbeda. Agar semakin dekat kesamaannya kita akan coba lagi untuk semakin mendekatkannya, yaitu dengan menyerahkan pembuatan object Rupiah dan Dollar oleh class Money, dengan katalain kita gunakan Factory pattern.

Akan sangat menyenangkan kalau kita bisa mengcreate Rupiah seperti ini,

[Test]
		public void Multiplication(){
			Rupiah sepuluhRupiah=Money.Rp(10);
			Assert.AreEqual(new Rupiah(20),sepuluhRupiah.Times(2));
			Assert.AreEqual(new Rupiah(30),sepuluhRupiah.Times(3));
			Assert.AreEqual(new Rupiah(50),sepuluhRupiah.Times(5)); 

		}

Agar bisa dicompile, implementasinya seperti ini,

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

Test saya jalankan dan ok.
Kita ingin agar reference ke Rupiah hilang dari test, maka

                [Test]
		public void Multiplication(){
			Money sepuluhRupiah=Money.Rp(10);
			Assert.AreEqual(new Rupiah(20),sepuluhRupiah.Times(2));
			Assert.AreEqual(new Rupiah(30),sepuluhRupiah.Times(3));
			Assert.AreEqual(new Rupiah(50),sepuluhRupiah.Times(5)); 

		}

Tetapi kompiler memberi tahu kita bahwa Money tidak memiliki method Times(). Karena itu kita harus membuat method Times() terdefinisi sebagai abstract di class Money dan tentu saja class Money harus berubah menjadi abstract juga.

public abstract class Money{
		...
		public abstract Money Times(int multiplier);
	}

Dan semua class turunan harus mengoverride method Times

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

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

	}

Test saya jalankan dan ok.
Dari sini kita bisa ubah deklarasi Factory menjadi,

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

Karena seluruh Factory untuk rupiah sudah kita buat maka semua kreasi object rupiah dalam test bisa kita ubah,

                [Test]
		public void Multiplication(){
			Money sepuluhRupiah=Money.Rp(10);
			Assert.AreEqual(Money.Rp(20),sepuluhRupiah.Times(2));
			Assert.AreEqual(Money.Rp(30),sepuluhRupiah.Times(3));
			Assert.AreEqual(Money.Rp(50),sepuluhRupiah.Times(5));
		}
		[Test]
		public void Equality(){
			Assert.IsTrue(Money.Rp(10).Equals(Money.Rp(10)),"10 rupiah TIDAK sama dengan 10 rupiah");
			Assert.IsFalse(Money.Rp(10).Equals(Money.Rp(5)),"10 rupiah sama dengan 5 rupiah");
			Assert.IsTrue(new Dollar(10).Equals(new Dollar(10)),"10 dolar TIDAK sama dengan 10 dolar");
			Assert.IsFalse(new Dollar(10).Equals(new Dollar(5)),"10 dolar sama dengan 5 dolar");
			Assert.IsFalse(new Dollar(10).Equals(Money.Rp(10)),"10 dollar sama dengan 10 rupiah");
		}

Test saya jalankan dan sukses. Dengan hilangnya referensi Rupiah dari dalam test, kita sekarang bebas berkreasi dalam turunan tanpa perlu khawatir akan terjadi kesalahan didalam test.

Berikutnya kita akan ubah Dollar mengikuti Rupiah. Dalam test perkalian Dollar, sebetulnya tidak ada bedanya dengan yang di Rupiah, yang semestinya bisa kita hapus saja karena pada akhirnya nanti akan membuat duplikasi. Tetapi jika kita melakukan, ini akan mengurangi rasa percaya diri kita untuk melakukan refactor. Jadi biarkan saja,

                [Test]
		public void Equality(){
			Assert.IsTrue(Money.Rp(10).Equals(Money.Rp(10)),"10 rupiah TIDAK sama dengan 10 rupiah");
			Assert.IsFalse(Money.Rp(10).Equals(Money.Rp(5)),"10 rupiah sama dengan 5 rupiah");
			Assert.IsTrue(Money.US(10).Equals(Money.US(10)),"10 dolar TIDAK sama dengan 10 dolar");
			Assert.IsFalse(Money.US(10).Equals(Money.US(5)),"10 dolar sama dengan 5 dolar");
			Assert.IsFalse(Money.US(10).Equals(Money.Rp(10)),"10 dollar sama dengan 10 rupiah");
		}
		[Test]
		public void DollarMultiplication(){
			Money sepuluhDollar=Money.US(10);
			Assert.AreEqual(Money.US(20),sepuluhDollar.Times(2));
			Assert.AreEqual(Money.US(30),sepuluhDollar.Times(3));
			Assert.AreEqual(Money.US(50),sepuluhDollar.Times(5)); 

		}

Jadi apa yang telah kita lakukan,

  • Berusaha sedemikan hingga mengeleminisai sedikit demi sedikit duplikasi code dengan mencari-cari segala sesuatu yang disamakan.
  • Kita telah memindahkan deklarasi method dari sub-class ke super-class.
  • Kita telah menghilangkan dependency test terhadap subclass dengan menggunakan Factory pattern.
  • Perhatikan, ketika sub-class menghilang akan ada beberapa duplikasi, jangan melakukan apapun.
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: