Prototype Pattern (Prototip Tasarım Kalıbı), mevcut bir nesnenin yeni bir örneğini oluşturmak için kullanılan oluşumsal tasarım desenlerinden (creational design pattern) biridir. Bu desen, new
operatörünü kullanmadan nesne oluşturmayı mümkün kılar. Bunun yerine, mevcut bir nesne klonlanarak yeni bir nesne elde edilir.
Ne Zaman Kullanılmalıdır?
Prototype Pattern şu durumlarda kullanışlıdır:
Nesne oluşturma maliyeti yüksek olduğunda: Büyük ve karmaşık nesneler tekrar tekrar oluşturulmak yerine mevcut nesneler klonlanarak performans artırılabilir.
Fabrika metodu (Factory Method) gibi nesne oluşturma desenlerinin yeterli olmadığı durumlarda: Nesne yapısının dışarıdan bilinmemesi gereken durumlarda, klonlama yöntemi daha güvenli olabilir.
Nesne yapılandırmasının değişken olduğu durumlarda: Örneğin, bir belge düzenleyicide kullanıcı farklı şablonlara dayalı yeni belgeler oluşturuyorsa, her defasında yeni bir belge nesnesi oluşturmaktan kaçınmak için prototip deseni kullanılabilir.
Runtime (çalışma zamanı) sırasında yeni nesneler üretmek gerektiğinde: Dinamik olarak nesne üretme ihtiyacı olan durumlarda.
Prototype Pattern'in Avantajları:
- Daha hızlı nesne oluşturma: Yeni bir nesne oluşturmak yerine mevcut nesneyi klonlamak daha hızlıdır.
- Bellek kullanımı açısından verimli: Nesnelerin gereksiz yere tekrar oluşturulmasını önler.
- Esneklik sağlar: Var olan nesnelerden türetilen nesneler üzerinde değişiklik yapılabilir.
- Bağımlılığı azaltır: Nesne oluşturma süreci istemci koddan soyutlanır.
Prototype Pattern'in Dezavantajları:
- Karmaşıklık artabilir: Deep copy (derin kopyalama) ve shallow copy (yüzeysel kopyalama) arasında dikkat edilmesi gereken farklar vardır.
- Java'da Cloneable arayüzünün sınırlamaları vardır:
Cloneable
arayüzü, yalnızca clone()
metodunun override edilmesiyle çalışır, ancak bazı durumlarda bu yeterli olmayabilir.
Shallow Copy ve Deep Copy Kavramları
Prototype Pattern Kullanım Biçimleri
1. Basit Prototype Kullanımı (Shallow Copy)
class Shape implements Cloneable {
private String type;
public Shape(String type) {
this.type = type;
}
public void draw() {
System.out.println(type + " çiziliyor.");
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// Kullanım
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Shape shape1 = new Shape("Daire");
Shape shape2 = (Shape) shape1.clone();
shape1.draw(); // Daire çiziliyor.
shape2.draw(); // Daire çiziliyor.
}
}
2. Deep Copy Kullanımı
class Address implements Cloneable {
private String city;
public Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new Address(this.city);
}
public String getCity() {
return city;
}
}
class Person implements Cloneable {
private String name;
private Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new Person(this.name, (Address) this.address.clone());
}
public void printInfo() {
System.out.println("Ad: " + name + ", Şehir: " + address.getCity());
}
}
// Kullanım
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("Ahmet", new Address("İstanbul"));
Person person2 = (Person) person1.clone();
person1.printInfo(); // Ad: Ahmet, Şehir: İstanbul
person2.printInfo(); // Ad: Ahmet, Şehir: İstanbul
}
}
Gerçek Dünya Senaryosu: Oyun Karakteri Klonlama
abstract class GameCharacter implements Cloneable {
private String name;
private int level;
public GameCharacter(String name, int level) {
this.name = name;
this.level = level;
}
public void showCharacter() {
System.out.println("Karakter: " + name + ", Seviye: " + level);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Warrior extends GameCharacter {
public Warrior(String name, int level) {
super(name, level);
}
}
// Kullanım
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Warrior warrior1 = new Warrior("Savaşçı", 10);
Warrior warrior2 = (Warrior) warrior1.clone();
warrior1.showCharacter(); // Karakter: Savaşçı, Seviye: 10
warrior2.showCharacter(); // Karakter: Savaşçı, Seviye: 10
}
}
Sonuç
Prototype Design Pattern, nesne oluşturma sürecini hızlandırarak özellikle büyük ölçekli sistemlerde performansı artıran bir tekniktir. Shallow Copy ve Deep Copy farklarına dikkat edilerek kullanıldığında, bu desen oldukça etkili bir çözüm sunar.