Thursday, September 17, 2009

Design Pattern in Brief (3)

Composite

Setiap komponen atau objek bisa dikelompokkan ke dalam salah satu dari dua kategori, individual komponen atau komposit komponen (yang terdiri dari individual komponen dan komposit komponen lain). Composite pattern digunakan untuk memodelkan sebuah interface sehingga kedua komponen tersebut bisa dilihat sebagai sebuah komponen yang sama dari sisi klien. Sederhananya, klien akan melihat dan bisa memperlakukan kedua komponen tersebut dengan cara yang sama.

Implementasi composite bisa dilihat pada tree, yang terdiri dari parent nodes dan leaves. Berikut ini kita mempunyai sebuah interface FileSystemComponent yang mempunyai method-method untuk megakses file komponen dan direktori komponen.



Method addComponent() pada class DirComponent digunakan untuk menambah file atau direktori baru di susunan file sistem tersebut. Sedangkan untuk mendapatkan ukuran dari file sistem yang ada, klien cukup memanggil getComponentSize(). Klien memperlakukan sama kedua file sistem tersebut, file dan direktori, untuk mendapatkan ukuran file sistem yang ada.

Design berikut adalah perbaikan dari design sebelumnya.



Kita bisa memanfaatkan interface atau abstract class dengan memindahkan semua method di DirComponent ke interface atau abstract tersebut. Karena class FileComponent tidak seharusnya memiliki method selain getComponentSize() maka FileComponent bisa throw exception jika method2 tersebut dipanggil dari dirinya. Sedangkan DirComponent harus mengoverride method2 tersebut.

public abstract class FileSystemComponent {
String name;
public FileSystemComponent(String cName) {
name = cName;
}
public void addComponent(FileSystemComponent component)
throws CompositeException {
throw new CompositeException(
"Invalid Operation. Not Supported");
}
public FileSystemComponent getComponent(int componentNum)
throws CompositeException {
throw new CompositeException(
"Invalid Operation. Not Supported");
}
public abstract long getComponentSize();
}

public class FileComponent extends FileSystemComponent {
private long size;
public FileComponent(String cName, long sz) {
super(cName);
size = sz;
}
public long getComponentSize() {
return size;
}
}

public class DirComponent extends FileSystemComponent {
Vector dirContents = new Vector();
//individual files/sub folders collection
public DirComponent(String cName) {
super(cName);
}
public void addComponent(FileSystemComponent fc)
throws CompositeException {
dirContents.add(fc);
}
public FileSystemComponent getComponent(int location)
throws CompositeException {
return (FileSystemComponent) dirContents.elementAt(
location);
}
public long getComponentSize() {
long sizeOfAllFiles = 0;
Enumeration e = dirContents.elements();
while (e.hasMoreElements()) {
FileSystemComponent component =
(FileSystemComponent) e.nextElement();
sizeOfAllFiles = sizeOfAllFiles +
(component.getComponentSize());
}
return sizeOfAllFiles;
}
}

Yang perlu diperhatikan adalah bahwa setiap kali kita menambah method baru, misal removeComponent() untuk DirComponent, maka kita juga harus menambahkannya di abstract atau interfacenya (dan FileComponent harus mengoverridenya). Kenapa? Karena kedua class child, FileComponent dan DirComponent, harus bisa dilihat dan diperlakukan sama oleh klien.

Saturday, September 12, 2009

Debugging in GWT

Days a go I tried to debug my GWT code and... nothing happened. In GWT, we can debug our code in hosted mode but not in web mode by the way. My breakpoint didn't hit by debugger. How could it be? After googling for awhile I found out that I'm not the only one who has the same problem. Some people say that they have problem when it is jdk 1.6.0_14, and when they downgrade to 1.6.0_13, it runs well without any debugging problems.

But before I revert back to older version, it's a good practice to upgrade first. So I decided to upgrade to 1.6.0.16 (currently available version). And when I run eclipse debugger, it works. Fiuh...

Design Pattern in Brief (2)

Prototype

Prototype bisa dipandang sebagai salah satu alternatif dari Factory dan Abstract Factory. Untuk memahaminya bisa dilihat pada contoh-contoh berikut.



Design di atas bisa diimplementasikan dengan abstract factory seperti berikut :



Dengan prototype kita bisa mengimplementasikannya seperti :





public class HostingPlanKit {
private HostingPlan basicPlan;
private HostingPlan premiumPlan;
private HostingPlan premPlusPlan;
public HostingPlanKit(HostingPlan basic, HostingPlan premium,
HostingPlan premPlus) {
basicPlan = basic;
premiumPlan = premium;
premPlusPlan = premPlus;
}
public HostingPlan getBasicPlan() {
return (HostingPlan) basicPlan.clone();
}
public HostingPlan getPremiumPlan() {
return (HostingPlan) premiumPlan.clone();
}
public HostingPlan getPremPlusPlan() {
return (HostingPlan) premPlusPlan.clone();
}


public class HostingPlanManager {
public static HostingPlanKit getHostingPlanKit(
String platform) {
HostingPlan basicPlan = null;
HostingPlan premiumPlan = null;
HostingPlan premPlusPlan = null;
if (platform.equalsIgnoreCase("Win")) {
basicPlan = new WinBasic();
premiumPlan = new WinPremium();
premPlusPlan = new WinPremPlus();
}
if (platform.equalsIgnoreCase("Unix")) {
basicPlan = new UnixBasic();
premiumPlan = new UnixPremium();
premPlusPlan = new UnixPremPlus();
}
return new HostingPlanKit(basicPlan, premiumPlan,
premPlusPlan);
}
}

Thursday, September 10, 2009

Shallow Copy & Deep Copy

Semua java class memilik method clone() yang diturunkan dari java.lang.Object. Method tersebut membuat copy dari sebuah object sebagai shallow copy. Apa yang dimaksud dengan shallow copy adalah :
1. Java membuat object baru di memori, termasuk membuat instance variabel yang bertipe primitive sekalipun.
2. Object lain yang direference oleh class yang diclone tersebut tidak dibuat copynya, hanya membuat reference baru ke object tersebut. Jadi kini ada dua reference yang mengarah pada object yang sama.

public class Car extends Object implements Cloneable {

private String carName;
private String carType;
private SUV suv;

public String getCarName() {
return carName;
}

public void setCarName(String carName) {
this.carName = carName;
}

public String getCarType() {
return carType;
}

public void setCarType(String carType) {
this.carType = carType;
}

public SUV getSuv() {
return suv;
}

public void setSuv(SUV suv) {
this.suv = suv;
}

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}

@Override
public String toString() {
return "carName : " + carName + " car type : " + carType + " suv : " + suv;
}

}

public class SUV {

private String suvType;
private String suvModel;

public String getSuvType() {
return suvType;
}

public void setSuvType(String suvType) {
this.suvType = suvType;
}

public String getSuvModel() {
return suvModel;
}

public void setSuvModel(String suvModel) {
this.suvModel = suvModel;
}

@Override
public String toString() {
return "suv type : " + suvType + " suv model : " + suvModel;
}

}

public class Main {

public static void main(String[] args) {
SUV suv = new SUV();
suv.setSuvModel("suv model 1");
suv.setSuvType("suv type 1");

Car car = new Car();
car.setCarName("Timor");
car.setCarType("Sedan");
car.setSuv(suv);

System.out.println("car 1 : " + car);
try {
Car car2 = (Car) car.clone();
suv.setSuvModel("suv model update");
System.out.println("car 2 : " + car2);
System.out.println("car 1 : " + car);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
car 1 : carName : Timor car type : Sedan suv : suv type : suv type 1 suv model : suv model 1
car 2 : carName : Timor car type : Sedan suv : suv type : suv type 1 suv model : suv model update
car 1 : carName : Timor car type : Sedan suv : suv type : suv type 1 suv model : suv model update

Sedangkan deep copy adalah :
1. Java menduplikasi object yang dicopy termasuk variabel yang primitif.
2. Object yang direference pun dicopy sehingga kini dua object yang diclone merefer ke dua object yang berbeda.

Bagaimana implementasi deep copy pada java? Kita bisa mengoverride method clone() untuk keperluan deep copy ini.

Monday, September 7, 2009

Design Pattern in Brief

Immutable

Immutable berarti tidak dapat diubah. Apanya yang tidak dapat diubah? Tentunya state dari suatu object, secara teknis, tentu nilai dari variabelnya. Dalam design pattern kita bisa membuat sebuah object menjadi immutable dengan cara
1. Semua instance variabel harus diset hanya dari konstruktor. Tidak ada method atau cara lain untuk mengeset nilai variabel selain dari konstruktor tsb. Dengan kata lain jadikan instance variabel private dan tanpa setter.
2. Agar class yang kita inginkan menjadi immutable tidak bisa di-extends, maka kita deklarasikan class tersebut sebagai final. Dengan demikian tidak ada cara untuk mengoverride method yang kita miliki.
3. Semua instance variabel harus dideklarasikan final sehingga hanya bisa diinisialisasi sekali, lewat konstruktor.
4. Jika sebuah method mempunyai return value berupa class dari object tersebut, maka sebaiknya ia tidak mengembalikan object yang sebenarnya melainkan copy atau clonenya.

Monitor

Menulis tentang monitor tentunya mengingatkan pada kuliah Sistem Operasi oleh Bapak Mochammad Husni :). Tak salah lagi, topik yang jadi hot thread pada kuliah itu adalah race condition, deadlock. Monitor adalah mekanisme yang digunakan untuk mengatasi deadlock sehingga hanya satu thread yang bisa mengakses sebuah method dalam satu waktu. Pada Java hal ini diatasi dengan mendeklarasikan sebuah method sebagai synchronized.

Factory



Factory dapat digambarkan sebagai sebuah class yang mengotomatisasi pembuatan sebuah object. Dalam diagram berikut kita memiliki sebuah parent class (bisa abstract, interface, atau konkret class) yang diextend oleh dua subclass. Sebuah class lain, yang bisa jadi bukan bagian dari aplikasi kita, ingin memanfaatkan class yang telah kita buat tersebut. Yang class lain tersebut ketahui hanyalah parent class saja. Mereka tidak tahu menahu struktur hirarki class kita. Sementara itu struktur yang kita buat adalah request harus didelegasikan ke masing-masing subclass yang bersesuaian. Bagaimana kita dapat menginstansiasi class-class yang berbeda dan mengembalikan return value dengan tipe yang sama adalah tugas Class Factory.

Pada gambar kita memiliki dua buah struktur factory. Pertama adalah sebuah interface sebagai contract dengan class lain. Kedua adalah Konkret class yang berisi factory method yang bertugas 'memilih' subclass mana yang harus diinstansiasi. Bagaimana cara factory method melakukan tugasnya? Sederhananya dengan if-then rules atau switch.

Singleton

Dalam design pattern, singleton berarti hanya ada satu instance. Bagaimana cara mendapatkan hanya satu instance selama aplikasi berjalan? Kita bisa melakukannya dengan meletakkan variabel dengan tipe class singleton sebagai global variabel, semua class yang membutuhkan object tersebut merefer ke variabel global yang dimaksud. Namun walaupun demikian, client masih tetap bisa membuat instance dari class tersebut bukan? Walaupun bukan sebagai global variabel.

Sebuah class yang bisa membuat dirinya sendiri hanya mempunyai satu instance disebut singleton class. Berikut adalah cara membuat class menjadi singleton
1. Buat constructornya private. Dengan demikian tidak ada cara class lain menginstansiasi class tersebut selain dirinya sendiri.
2. Di dalam class singleton tersebut buat public static method dengan nama getInstance().
3. Di dalam body method getInstance() buat instance yang hanya dibuat sekali pada saat pertama class di-invoke.

public class Singleton {
private static final Singleton INSTANCE = new Singleton();

// Private constructor prevents instantiation from other classes
private Singleton() {}

public static Singleton getInstance() {
return INSTANCE;
}
}

Pada code di atas, instance singleton dibuat hanya sekali yaitu saat class dipanggil. Namun cara ini memiliki kelemahan yaitu instance dibuat saat pertama class diinisialisasi, bukan saat dipanggil.

public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}

/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}


Code di atas adalah yang diusulkan oleh Bill Pugh. Instance benar-benar dibuat saat getInstance() dipanggil, bukan saat class diinisialisasi.
AbstractFactory

Untuk memahami AbstractFactory perhatikan gambar berikut



















public class LuxuryVehicleFactory extends VehicleFactory {
public Car getCar() {
return new LuxuryCar("L-C");
}
public SUV getSUV() {
return new LuxurySUV("L-S");
}
}

public class NonLuxuryVehicleFactory extends VehicleFactory {
public Car getCar() {
return new NonLuxuryCar("NL-C");
}
public SUV getSUV() {
return new NonLuxurySUV("NL-S");
}
}

public abstract class VehicleFactory {
public static final String LUXURY_VEHICLE = "Luxury";
public static final String NON_LUXURY_VEHICLE = "Non-Luxury";
public abstract Car getCar();
public abstract SUV getSUV();

public static VehicleFactory getVehicleFactory(String type) {
if (type.equals(VehicleFactory.LUXURY_VEHICLE))
return new LuxuryVehicleFactory();
if (type.equals(VehicleFactory.NON_LUXURY_VEHICLE))
return new NonLuxuryVehicleFactory();
return new LuxuryVehicleFactory();
}
}

Wednesday, September 2, 2009

JVM terminated. Exit code=-1

Have you ever got the above error message when you try to launch eclipse? Well it happened yesterday. When I started eclipse, it showed this error window



This error is quiet strange since I did fresh install jdk and eclipse on my windows machine. When I googled this error, there were some advices including to increase Xms512. But it did work before without setting anything. Then finally I found a good advice here : http://www.coderanch.com/t/423852/IDEs-Version-Control-other-tools/IRAD-JVM-Terminated-Exit-Code.

Yup. Remove the entries in eclipse.ini :). But unfortunately after you do that, there will be an error saying that you need to close your eclipse. To deal with this, you need to restore your eclipse.ini file (you can try another eclipse.ini file or just restore the last one) and change this :
-Xmx512m to Xmx256m.

People says that it happens because eclipse tries to allocate heap memory as much as 512 but it fails.
 

©2009 Stay the Same | by TNB