TASARIM ÖRÜNTÜLERİ

Prototype

Creational Patterns bir örneği olan Prototype örüntü; nesnenin bir kopyasını oluşturmanın zahmetli olduğu, zaman aldığı durumlar için bellekteki bir kopyasının oluşturularak bunu Map üzerinden kullandırır.

Onur Dayıbaşı
Design Patterns

--

Bilgi Notu: Diğer tüm Tasarım Örüntüleri yazıma bu linkten ulaşabilirsiniz.

Hangi Durumda

Normal zamanda nesnenin oluşması için geçen süre kısadır. Fakat oluşturduğumuz nesnenin bir takım bilgileri bir dosyadan veya veritabanından veya bir servisten doluyorsa bu nesneyi “cache’lememiz” avantajlı hale gelecektir.

Veya bir nesne oluşturacağız sınıftaki öğrenciler örneğin. Bu nesnede bir sürü ortak özellik olduğu, sadece isim , soyad ve no değişecek ise new ile nesne oluşturmak yerine mevcut bir nesnenin clone oluşturup bu yeni nesnede daha az değişiklik yaparak kullanabiliriz.

Bazen orjinal nesne üzerinde (state) üzerinde işlem yapmak yerine onun clone üzerinde işlem yapıp sonrasında bu nesneyi atmakta isteyebiliriz.

Tüm bu işlemler yapabilmek için Shape arayüzünde clone metodu olmalı. Bundan türeyen sınıflar Circle, Rectangle, Square kendisini nasıl clone oluşturacağını bilmelidir.

Burda immutable primitif değerler için Shallow Copy işe yarayabilir ama referans nesneler için Deep Copy yapılması gerekmektedir.

Prototype Pattern Class Diagram

Aşağıdaki örnekte görüldüğü gibi Shape sınıfı “Cloneable” sınıfından türemektedir. Bundan oluşturulan Rect, Square, Circle gibi sınıflar klonu oluşturulabilen nesnelerdir.

Shape Arayüzü
Concrete Shape Classları

Bu kısımda getShape metodu “cache’den” dönen nesnenin clone aldığı için nesne klonlama işlemini istemciden soyutlamaktadır.

ShapeCache
ShapedCache Kullanan İstemci

Avantajları

Eğer mevcut durumda elimizde bir A arayüzünden türeyen AConcrete olsun bunun bir çok özelliği var ise ve bu clone nesnelerin içerisine almadığımız durumda kodun farklı yerlerinde kendi new nesnemizi oluşturup buna değerleri setleme işlemlerini dışarı taşımamız gerekir.

aClone=new AConcrete2()
aClone.x=instance.x
....

OO Geliştirmede en önemli konulardan birisi new işlemini olabildiğince kontrollü yapmaktır. Bundan dolayı new yapılan kısımlardaki nedenselliklere göre tasarım örüntüleri oluşturulmuştur.

Extra Bilgi : JS Nesneyi Kopyalama Yöntemleri (Shallow/Deep Copy)

Shallow(Sığ) kopyalama esnasında sadece first-level (birincil) hiyerarşideki değerleri kopyalar. Spread operatörü’ de bu kopyalamaya göre çalışır.

Deep(Derinlemesine) kopyalama ise bütün alt hiyerarşileri gezip her bir değeri kopyalar bu zahmetli ve uğraştırıcıdır ama referansların birbirini etkilememesi için deep copy zorunludur.

Shallow Copy

let obj = { a: [1, 2, {users: [{ name: ‘onur’, age: 12 }] }], b:2 };
const cloneObj={…obj}; //same => Object.assign({}, obj);
obj.a[2].users[0].name=’deniz’;
obj.b=4;
console.log(cloneObj);//Result interesting..
//cloneObj.b is 2 not 4 because it clones first level and cloneObj holds a new memory location for b
//but cloneObj.a[2].users[0].name is 'deniz' why because it hold reference cloning is not deeply.

Deep Copy

  1. Serialize/Deserialize : Hızlı kopyalama için — JSON.parse/stringify kullanabilirsiniz.

2. lodash.clonedeep

const clonedeep = require('lodash.clonedeep')

3. Recursive olarak nesneyi dolaşarak birbirine atama yaparak kopyalama yapabilirsiniz.

function clone(obj) {
if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
return obj; if (obj instanceof Date)
var temp = new obj.constructor(); //or new Date(obj);
else
var temp = obj.constructor(); for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
obj['isActiveClone'] = null;
temp[key] = clone(obj[key]);
delete obj['isActiveClone'];
}
}
return temp;
}

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--