20 Mart 2008 Perşembe

Prototype Pattern

Bir sınıftan birden fazla nesne yaratma ihtiyacı duyarız fakat bu işlem hız ve bellek yönetimi açısından maliyetli bir iştir. Bunun yerine o nesnenin orjinal kopyasını yapmak bize önemli ölçüde kazanç sağlayacaktır. Burada “new” operatörü yerine clone() methodu kullanılır. Bu metodu kullanırken dikkat etmemiz gereken hususlar ya da avantajları ve dezavantajlarını da belirtelim.

1) private alanlar direkt olarak atanmaz yani setter ve getter alanlara ihtiyaç duymaktadır, bu da fazla kod maliyeti olarak görülmektedir.//Dezavantaj
2) clone() metodu nesnenin bellekteki alanını bir işlemde kopyalamaktadır. Bu da nesneyi yaratmaya gore çok daha hızlıdır.

x.clone() != x // bu ifade doğru; aynı referans id lerine sahip değiller.
x.clone().getClass() == x.getClass() // bu ifade doğru; aynı sınıfın farklı id lerde.

Person adında bir sınıfımız olsun, bu sınıfın adı, soyadı alanları olsun. Person sınıfını yaratalım ve alanlarına atama yapalım.

Person person = new Person();
person.setName(“Asin”);
person.setSurname(“Akdeniz”);

yaratıp atamaları yaptıktan sonra clone lama işlemine geçelim.

Person person2 = person.clone();

System.out.println(“Name:”+person2.getName());
System.out.println(“Surname:”+person2.getSurname());

Beklenen Çıktı,
Name : Asin
Surname: Akdeniz

Devam edelim,
person2.setName(“Ersin”);

System.out.println(“Name:”+person2.getName());
System.out.println(“Name:”+person.getName());
Beklenen Çıktı,
Name: Ersin
Name : Asin

Sonuç olarak clone() lama ile referans atamıyoruz, bunu clone() lanmış nesnemizin alanlarını değiştirince orjinal nesnemizin durumuna yansımaması ile daha net gorebiliyoruz. Aşağıdaki ifadeyi incelerseniz arasındaki farkı daha net gorebilirsiniz.

Person person = new Person();
Person person2 = person;

Yukarıdaki ifadede ilk satırda bir Person sınıfına ait bir nesne yaratılmıştır.İkinci satırda ise oluşturmuş olduğumuz bu nesneye bir referans vardır yani oluşturulan bu nesneye ulaşırken person2 ya da person yazarak ulaşabiliriz.

clone() metodunun kullanılması için
• Clonable interface nin implement edilmesi lazım.
• Nesne clone’lanmayınca CloneNotSupported Exception fırlatır.

public class Person implements Cloneable{
private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public static Person getPerson(Person person){
try {
return (Person) person.clone();
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Person.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}

public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setName("Asin");

Person perClone = Person.getPerson(person);
System.out.println("Name:"+perClone.getName());
perClone.setName("Ersin");
System.out.println("Person Name:"+person.getName());
System.out.println("Person (Clone) Name:"+perClone.getName());
System.out.println(perClone);
System.out.println(person);
}

}
Beklenen Çıktılar...
Name:Asin
Person Name:Asin
Person Clone Name:Ersin
clonejavs.Person@12dacd1
clonejavs.Person@1ad086a

2 yorum:

Adsız dedi ki...

Prototype pattern Factory pattern ile birlikte kullanılmalıdır. Fabrika sınıfı (üretken sınıf) prototip örnekleri bünyesinde barındırır, kendisinden yeni bir nesne talep edildiğinde talep edilen tipe uygun prototipi klonlar ve arzeder. Bu güzel çalışma için teşekkürler.

Ender MENTEŞ dedi ki...

Ellerinize sağlık. Diğer patternleride en kısa sürede bekliyoruz.