JavaScript Temelleri

Bölüm 15

Kullanıcı Tanımlı Nesneler

Bölüm 15 Sayfa 3

15.2.2 - Kullanıcı Tanımlı Nesnelerin Yapılandırıcı Fonksiyonlar ile Yapılandırılması

Bir nesne sınıf yaratılması için, bir yapılandırıcı fonksiyonun tanımlanması gereklidir. JavaScript programlama dilinde, her fonksiyon yapılandırıcı fonksiyon olabilir. Tanımlanan her fonksiyon için, JavaScript yorumlayıcısı otomatik olarak bir prototype özelliği oluşturur. Bu özelliğin değeri, nesne sınfının prototip nesnesidir. Bu nesne, nesne sınıfından bir örnek oluştuğunda, bu örneğin sahip olacağı özellikleri belirler.

Bir önceki bölümde, bir nesne sınıfının en basit yapılandırıcı fonksiyonun, sadece fonksiyon ismi (dolayısı ile nesne sınıfı ismi) olan boş bir fonksiyon olabileceği görülmüştü. Boş bir yapılandırıcı fonksiyon, sınıfın prototipinin (yapılandırıcı fonksiyonun prototype özelliğinin değerinin) oluşması için yeterli olduğu, boş prototip nesnesinin oluştuktan sonra geliştirilebileceği görülmüştü. Bu bölümde, yapılandırıcı fonksiyonları biraz daha ileri taşıyacak, bu fonksiyonları hem tanımladıkları nesne sınfının özelliklerini belirleyen, hem de bu sınıfın üretilecek nesne örneklerinin özellikerine değer atayabilecek yapıya kavuşturmaya çalışacağız.

JavaScript programlama dilinde, yapılandırıcı (constructor) fonksiyonlar, nesne örneklerini belirli özelliklere sahip olacak ve bu özelliklerin özdeğerlerini verebilecek şekilde tasarlanmış fonksiyonlardır. Yapılandırıcı fonksiyonların özel bir tanıtım şekilleri yoktur. JavaScript programlama dilinde, tüm fonksiyonlar yapılandırıcı fonksiyon olarak kullanılabilirler, fakat ancak belirli yapı özelliklerini taşıyan fonksiyonlar kendilerinden beklenilen işlevleri gereği gibi yerine getirebilirler. Yapılandırıcı fonksiyonlarda return ifadesi yoktur.

Bir JavaScript yapılandırıcı fonksiyonun temel işlevi, fonksiyonun ismi ile tanımlanan yeni bir nesne sınıfı prototipini belirlemektir. Bir önceki bölümde bu işlevin basit bir boş fonksiyonla gerçekleştirilebileceğini görmüştük. Bundan sonra, oluşturulan boş nesne örneklerinin protiplerine eklemeler yapılarak nesne sınıfının özellikleri belirlenmekteydi. Bundan sonra da özellikleri belirlenmiş sınıfların örnekleri oluşturulmakta ve oluşturulan örneklerin özellik değerlerine verilerin atanmasını kolaylaştırmak üzere veri giriş fonksiyonlarından yararlanılmaktaydı.

Bu bölümde, yapılandırıcı fonksiyonların, nesne sınıflarının protiplerini oluşturma yanında, prototipe çeşitli özellikler (metotlar özelliklere dahildir!) eklenmesini ve bu özelliklere başlangıç değerleri atanmasını sağlayabileceklerini göreceğiz. İlk olarak, en basit yapılandırıcı fonksiyon olan boş fonksiyondan bir ileri düzey yapılandırıcı fonksiyon, nesne özelliklerini belirten ve bu özelliklere bir sabit değer atayan türde bir yapılandırıcı fonksiyondur. Böyle bir yapılandırıcı fonksiyon örneği aşağıda görülmektedir :

...
function üretim() {
this.seriNumarası = 0;
this.müşteri = 'stok';
this.malzemeMaliyeti = 0;
this.emekSaat = 0;
this.toplamMaliyet = function() {
var maliyet = 0;
maliyet = (this.malzemeMaliyeti + this.emekSaat * 10) * 1.2;
return maliyet;
}
}
...
		

Yukarıda görülen yapılandırıcı fonksiyonun yapısı bir çok noktalardan karakteristik bir yazılımdır. Her yapılandırıcı fonksiyonda bir this saklı sözcüğü bulunur. Bir yapılandırıcı fonksiyon içindeki this saklı sözcüğü, yapılandırıcı fonksiyonu oluşturacağı nesne örneğini belirtir. Yani bu örneğin seriNumarası özelliği vb. gibi anlam taşır. toplamMaliyet Metodunun değeri olan fonksiyon, bu nesne sınıfının bir metodudur ve her metotta olduğu gibi, this saklı sözcüğü, metodu çağıran nesneye işaret eder.

Bir yapılandırıcı fonksiyonda özelliklere atanacak fonksiyonlar istenirse, bir önceki bölümde verilen örneklerde olduğu gibi, yapılandırıcı fonksiyon dışında da tanımlanabilir ve yapılandırıcı fonksiyondaki özelliğe referansı atanabilir. Bu yöntem aşağıda görülmektedir:

...
function maliyetHesabı() {
var maliyet = 0;
maliyet = (this.malzemeMaliyeti + this.emekSaat * 10) * 1.2;
return maliyet;
}

function üretim() {
this.seriNumarası = 0;
this.müşteri = 'stok';
this.malzemeMaliyeti =0;
this.emekSaat = 0;
this.toplamMaliyet = maliyetHesabı;
}
...
		

Bir metodun içeriğinin, yapılandırıcı fonksiyonun içinde veya dışında tanımlanması arasında fark yoktur ve seçim sadece programcının kişisel seçimine bağlıdır. Fakat, metot içerikleri yapılandırıcı fonksiyonlardan bağımsızdır ve yapılandırıcı fonksiyonların dışında tanımlanmaları, belki de daha düzenli ve daha kolay izlenebilen bir program yazılım stili olabileceği söylenebilir.

Yukarıda açıklanan yapılandırıcı fonksiyonun esneklikten uzak olabileceği düşünülebilir. Gerçekten bu fonksiyon işlevini gayet iyi yerine getirebilecek, fakat oluşturduğu nesne örneklerinin özelliklerine sadece varsayılan değerler atanmış olacaktır. Bundan sonra, özelliklere gerçek değerlerin girilebilmesi için, başka veri giriş fonksiyonlarına gereksinme duyulacaktır. Bu nedenle, yapılandırıcı fonksiyonlara biraz esneklik kazandırılıp, özelliklere gerçek değerlerin girilebilmesine olanak sağlayacak şekilde düzenlenmeleri iyi bir gelişme olacaktır. Böyle düzenlenmiş olan yapılandırıcı fonksiyonlar, aşağıda görülmektedir:

...
function maliyetHesabı() {
var maliyet = 0;
maliyet = (this.malzemeMaliyeti + this.emekSaat * 10) * 1.2;
return maliyet;
}

function üretim(nr, siparişVeren, bedel, , saat) {
this.seriNumarası = nr;
this.müşteri = siparişVeren;
this.malzemeMaliyeti = bedel;
this.emekSaat = saat;
this.toplamMaliyet = maliyetHesabı;
}
...
		

Bu şekilde oluşan nesne örneklerinin özelliklerine güncel değerler atanmış olacaktır. Fakat, bu da yeterli bir esnekleik kazanımı sayılmayabilir. Bazı durumlarda, nesne örneklerinin tüm özellik değerlerinin birden girilmesine olanak bulunmayabilir. Bazı özellik değerleri daha sonra girilmek istenebilir. Yapılandırıcı fonksiyonun argümanları üzerine, bir önceki bölümde görülen veri giriş fonksiyonlarında uygulanmış olduğu gibi, argümanlar üzerinde mantıksal kontrollerin yapılması ve eksik olan veya uygun olmayan değerler yerine, varsayılan değerlerin atanmasının sağlanması çok istenen bir gelişme olabilir. Böyle bir yapılandırıcı fonksiyon ve bu yapılandırıcı fonksiyon kullanılarak oluşturulan bir nesne örneğinin özellik değerleri bir uygulama sayfasındaki görüntülenme sonuçları aşağıda görülmektedir:

...
function maliyetHesabı() {
var maliyet = 0;
maliyet = (this.malzemeMaliyeti + this.emekSaat * 10) * 1.2;
return maliyet;
}

function üretim(nr, siparişVeren, bedel, saat) {
this.seriNumarası = nr || 0;
this.müşteri = siparişVeren || 'stok';
this.malzemeMaliyeti = bedel || 0;
this.emekSaat = saat || 0;
this.toplamMaliyet = maliyetHesabı;
}

var parça = [];
parça [0] = new üretim(1203200978, 'Havlucular', 4200, 64);
bilgiYaz('parça[0] :', 'b15.2.2-uyg-1-sonuç-1');
sonuçYaz('parça[0].seriNumarası : ', parça[0].seriNumarası, 'b15.2.2-uyg-2-sonuç-2');
sonuçYaz('parça[0].müşteri : ', , parça[0].müşteri, 'b15.2.2-uyg-2-sonuç-3');
sonuçYaz(' parça[0].malzemeMaliyeti : ', parça[0].malzemeMaliyeti, 'b15.2.2-uyg-2-sonuç-4');
sonuçYaz('parça[0].emekSaat : ', parça[0].emekSaat, 'b15.2.2-uyg-2-sonuç-5');
sonuçYaz('parça[0].toplam Maliyet : ', parça[0].toplamMaliyet(), 'b15.2.2-uyg-2-sonuç-6');

...
		

Program Sonucu :

Yukarıdaki uygulamada görüldüğü şekliyle, en son geliştirilmiş olan yapılandırıcı fonksiyon esnek ve işlevsel bir yapılandırıcı fonksiyon şeklidir. Buna rağmen, gereksinmelere göre değişik ve daha sıkı kontroller içeren, uygun olmayan verilerin girilmesine olanak vermeyen türde yapılandırıcı fonksiyonlar oluşturulabilir. Olanaklar sonsuzdur.

Nesne sınıfları ile yapılacak çalışmalarda, nesne sınıfının veri yapısı ilk önce programcının düşüncesinde tam olarak şekillenmelidir. Nesneler, uzun soluklu programlarda çalışılacak verilerdir. Bu verilerin veri yapısı başlangıçta iyi bir şekilde planlanmalıdır. Baştan yetersiz olarak düzenlenmiş veri yapılarının ileride geliştirilmeleri çok kolay olmayabilir. Örnek olarak yine bir sosyal klübün üyelerinin veri yapısını planlamaya çalışalım. Her üyenin herşeyden önce bir üye numarası olması gerekir. Bunun nedeni, bilgisayarda aramaların sözel yerine sayısal verilerle yapılmasının daha etkili olmasıdır. Bu durumda veri yapısının ilk alanı sayısal bir değer alacak üye numarası alanıdır. Bu alan, veri yapısında belirli bir ismi olan bir değer özelliği ile ifade edilir. Bu değer özelliğine nr adını verelim. Klüp üyeleri sınıfına da Üye adı verelim. Konvansionel olarak sınıf adları büyük harfle başlar. Bu durumda, Üye() sınıfının veri yapısı ilk aşamada, nr isimli bir tamsayı değer alacak özelliğe sahip olacaktır. Bu özellikten başka, isim ve soyad adında iki sözel alan da veri yapısında bulunacaktır. Veri yapısı, programcı ve projeyi veren kuruluşun istekleri doğrultusunda oluşacaktır. Projenin uygulanacağı klüp yetkilileri, her üyenin kayıt ayını görmek ve her üyenin aidat borcunun hesaplanmasını programcıdan istemişlerdir. Kayıt ayı kayıtAyı adında sözel bir alanın veri yapısına eklenmesi ile çözümlenebilecektir. Her üyenin yıllık aidat borcunun hesaplanabilmesi için, üye veri yapısına bir metot eklenmesi gerekecektir. Bu yapı tüm üyelerin ortak olarak paylaşacakları bir yapı olacaktır. Yani, klübün her üyesi için, bu veri yapısındaki özelliklerin her birinin bir değeri olacaktır. Her bir sınıf üyesi veya nesne örneği, veri yapsındaki alanlara değişik veriler girilerek oluşturulabilecektir.

Öngörülen veri yapısının yeterli olup olmayacağı kolay yanıtlanabilecek bir soru değildir. Doğal olarak dinamik bir dünyanın gereksinmeleri statik bir veri yapısı ile uzun süre karşılanamaz. İleride veri yapısına yeni alanlar eklenmesinin gerekeceği tartışma götürmez. Yine de iyi organize edilmiş bir veri yapısının, bir veri temelinin uzun süre gereksinmelerini karşılayabileceği söylenebilir. Bu sorunun iki yönü bulunmaktadır. Bunlardan ilki yönetseldir. Projeyi verenler isteklerini iyi analiz etmeli ve programcı ile iyi bir iletişim ve empati kurarak isteklerini iletmelidir. İkinci konu ise çalışamanın teknik yönüdür. Programcının kendisine iletilen istekleri teknik olarak iyi analiz etmelidir. Örnek olarak, programcı teknik gereklerle her üyeye bir üye numarası vermektedir. Bu üye numarası, istenirse klüp yazışmalarında kullanılabilir. Fakat projeyi veren istemese bile, programcı bu veri alanını salt teknik gereksinmeler için veri yapısına ekleyecektir. Burada kritik sorulardan biri, veri yapısında öngörülen özelliklerin değerlerinin sorgulanması ile üyelerin diğerlerinden farklandırılabilmesi sağlanabilecek midir? Diğer bir söylemle, bu veri yapısı için seçilmiş olan özellikler ayırdedici midir? İsmi aynı, iki üye olabilir. Adresi aynı iki üye de olabilir. Fakat, hem adı hem soyadı, hem de adresi aynı olan iki üye bulunmasının olasılığı çok zayıftır. Ayrıca, teknik nedenlerle veri yapısına eklemiş bulunan üye numarası alanı, her üyeye faklı bir üye numarası vererek her kaydın diğeri ile aynı olmamasını kesinlikle sağlayacaktır. Bu durumda, veri yapısı için seçilmiş olan özellikler, bugün için sosyal klüp idarecilerinin isteklerini karşılayacak düzeyde sayılabilir. İleride ortaya çıkacak gereksinmeler için ise, veri yapısına her zaman eklemeler yapılabilir. Fakat, her zaman belirtidiği gibi, en iyisi işi baştan sıkı tutarak, gereksinmelere yanıt verecek en uygun veri yapısının oluşturulmasına çalışılmasıdır.

Bu şekilde klüp üyeleri için bir bilgi prototipi oluşturmuş oluyoruz. JavaScript programlama dili, nesne yapılanmalarını, nesne prototipleri yardımı ile sistematize eder. Prototipte, bir nesnenin tüm özellikleri ve metotları bulunmaktadır. Klüp üyelerinin bilgi prototipi, üye numarası, ad, soyad kayıt ayı özelliklerinden ve aidat borcunu hesaplayacak bir metottan oluşacak şekilde belirlenmiştir Üye nesne tipininin prototipi bu şekilde kesin şeklini almıştır. Prototip bir üyenin üye numarası, ad, soyad, kayıt ayı özellikleri olacak ve bu bilgilerden yararlanılarak yıllık aidat ödentisini hesaplayacak bir metodu olacaktır. Bu prototipe uyan her nesne, Üye nesne tipinin farklı bir oluşumu olacaktır. Bundan sonra yapılması gereken, Üye nesne tipini ve bu tipe uyan nesneleri programa tanıtmaktır. Bunun için bir yapılandrıcı fonksiyon aşağıda görülmektedir:

function aidat() {
return (12 - this.kayıtAyı) * 5;
}

function Üye(nr , ad , soyad , ay) {
this.numara = nr;
this.isim = ad;
this.soyad = soyad;
this.kayıtAyı = ay;
this.aidat = aidat;
}
		

Burada this saklı sözcüğü, yapılandırıcı fonksiyonu çağıran nesne örneğini belirtmektedir. Bu sözcüğü, "onun özellikleri" olarak düşünmek gerekir.

Yukarıdaki yapılandırıcı fonksiyon kullanılarak, aşağıda görülen JavaScript programında , bir dizinin elemanları olarak nesne örnekleri yaratılmıştır.

...
üye = [];
üye[0] = new Üye(10 , 'Muharrem' , 'Alver' , 2) ;
document.getElementById('aidat').value = üye[0].aidat();
...

Bu programın, bağlantılı olduğu uygulama sayfasında , verdiği sonuç, aşağıda görülmektedir:

Programın uygulama sonucu:

Nesneleri, nesne dizilerine yerleştirmek son derece mantıklıdır. Bu şekilde daha sistematik ve kompakt kodlar ile çalışma olanağının sağlanması yanında, verilerin saklanması ve verilere erişim daha kolay gerçekleştirilebilmektedir. Modern veri temelleri de, verileri bir veri yapısı halinde tanımlayıp, bu veri yapısında binlerce nesne örneği (kayıt) oluşturarak bu kayıtların disk dosyalarında saklanmasını sağlarlar. Bu kayıtlar dinamik karakterdedir ve istendiğinde çağrılıp güncellenip yeniden diskte saklanabilirler. İleride görececeğimiz gibi, JavaScript'in Microsoft tarafından geliştirlen ve Internet Explorer tarafından desteklenen JScript sürümü, disk dosyalarını destekler. Fakat bir programlama dili ile bir veri tabanı arasındaki fark, dosyaların diskte saklanması, kayıtların aranması ve yeniden yerleştirilmesi için geliştirilmiş özel tekniklerdir. İkili arama (binary search), Indexed Sequential Access Method (ISAM) gibi gelişmiş teknolojilerin kullanıldığı veri temelleri, büyük sayıda kayda çok kısa sürede erişim sağlayabilecek yetenektedir. Düz sıralı kayıt tekniği kullanabilen program dilleri bu yetenekten yoksundur ve sadece az sayıda kaydı dinamik olarak çalıştırabilirler. Bu nedenle, çok sayıda nesne örneği kullanımını gerektiren büyük projelere, JavaScript gibi programlama dillerinden, özel dosyalama teknikleri kullanımı sağlayan ek veri temeli programlarına giriş sağlanması düşünülmelidir. Normal tekniklerle de veri yapısına bağlı olarak binlerce dinamik kaydın yöntemi sorunsuzca sağlanabilmekte ve bu da birçok küçük proje için yeterli olabilmektedir. Büyük projeler için, JavaScript programlama diline veri temeli desteği sağlayan ticari programlar piyasada bulunmaktadır.

Nesne dizilerinin bir başka uygulaması olarak bir stok kontrol programı oluşturalım. Bir depo içindeki malzemelerin takibini yapmak için, yapılan bir JavaScript programında Veriler için, ayrı bir dış JavaScript sayfası kullanılmıştır. Verileri ayrı bir sayfada tutmanın mantığı, verilerin güvenliğinin sağlanması, yapılabilecek bir yanlışlıkla verilerin silinmesi olasılığının azaltılmasıdır. İleride, verileri diskte standart metin dosyaları halinde saklayıp, disk dosyası olarak erişimin yöntemleri de açıklanacaktır. Verilerin JavaScript program dosyasında aşağıdaki kodlar bulunmaktadır:

function Malzeme (numara , isim , açıklama , stokSayısı , üretici) {
this.nr = numara;
this.ad = isim;
this.açıklama = açıklama;
this.stokSayısı = stokSayısı;
this.üretici = üretici;
}
// Sentetik Verilerin Üretimi (veriler Dosyasında)

var stok = [];

...
stok[44] = new Malzeme(4 , 'Motor Kapak Contası' , 'Özel Conta' , 5 , 'İlke Keçe Sanayii A.Ş.');
...
		

Veri dosyasında , 50 sentetik kayıt üretilmiştir. Her kayıt, Malzeme sınıfından bir örnek ve stok dizisinin bir elemanıdır. Bu program nesne dizileri kullanmaktadır. Bu şekilde duruma göre binlerce kayıt kolaylıkla ve sistem yavaşlaması olmadan yönetilebilir. Bu sayı, bir arkadaş listesi, kişisel müzik dosyaları arşivi, küçük işletmelerin kayıtları gibi statik kayıt sistemi yeterli olan her tür veri çalışmasında yeterlidir. Statik kayıtlar, istendiğinde kayıt dosyası açılarak notepad veya vi gibi bir metin editörü kullanılarak kolaylıkla güncellenebilir. Bu uygulamada statik kayıt dosyasında bulunan kayıtların her biri, Malzeme sınfının bir örneği ve stok dizisinin bir elemanıdır. Bu olanaklar, çok sayıda orta boy proje için yeterli olmaktadır.

JavaScript, ECMA-262 spesifkasyonu ile sınırlı yerleşmelerinde disk dosyalarına erişimi gerektiren dinamik veri uygulamalarını prensip olarak desteklemez. Web uygulamalarından gelebilecek etkileri engellemek için, JavaScript programlama dili baştan böyle tasarlanmıştır. Yine de zamanla bu dilin olağanüstü gelişimi ve popülaritesi, disk dosyalarının eksikliğini hissettirmiştir. Bu gereksinmeyi karşılamak için, Microsoft'un özel JavaScript sürümü olan JScript de bu olanak sağlanmıştır. Bu olanak, sadece Intenet Explorer de desteklenmekledir. Kullanıcıların büyük çoğunluğu da IE kullandığından bunun aşırı bir sakıncası yoktur. Biz çalışmalarımızda JScript disk dosyalarının uygulamalarını tanıtacağız. Standartları sadece bu konuda aşmış olacağız. Bunun dışında tüm uygulamalar IE, FireFox ve Opera gibi kullanıcıların tümüne yakının kullandığı belge çözümleyicilerde çalışacaktır.

Bazı durumlarda, nesne örnekleri, doğrudan yapılandırıcı fonksiyonlarla değil, yapılandırıcı fonksiyonları çağıran veri giriş fonksiyonları yardımı ile yaratılırlar. Bu yönteme zorlamalı nesne örneği yaratılması adı verilir ve instanceof işlemcisinden yararlanılır. Veri giriş fonksiyonlarının yaraıı, istenildiği kadar esnek olabilmeleri ve her türlü yöntemle veri girişi sağlayabilmeleridir. Aşağıda görülen JavaScript programında, böyle bir veri giriş fonksiyonu kullanılmıştır. Bu program bir web formudur. Bu tür formlar, ilerideki çalışmalarda disk dosyalarına veri yazımı amacı için kullanılacaktır. İleride hem bu tür web formlarının oluşturulması hem de verilerin disk dosyaları üzerinde saklanması konularında yoğun çalışmalar yapılacaktır. Bu programın ilişikli olduğu sayfadaki çalışmasını görmek için, lütfen aşağıdaki bağlantıyı tıklayınız.

function Klüp Üyesi (nr, ad , soyad , ay) {
if(! (this instanceof Üye)) {
return new KlüpÜyesi(nr , ad , soyad , ay);
}
this.numara = nr;
this.isim = ad;
this.soyad = soyad;
this.kayıtAyı = ay;
}


function oku(x) {
return document.getElementById(x);
}


// oku() fonksiyonu bdelib.js program kitaplığına eklenmiştir.


function KayıtEkle() {

var klüpÜyesi = new Array();

var a = null, b = null, c = null, d = null;

a = document.getElementById("nr").value;

b = document.getElementById("ad").value;

c = document.getElementById("soyad").value;

d = document.getElementById("ay").value;

if(! isFinite(parseInt(a ))) {

alert('Üye Numarası Bir Tamsayı Olmalıdır !');
}

else if (isFinite(parseInt(b , 10))) {

alert('Üye Adı Sayısal Olamaz !');
}

else if(b === '') {

alert('Lütfen Üye Adını Giriniz !');
}

else if (isFinite(parseInt(c , 10 ))) {

alert('Üye Soyadı Sayısal Olamaz !');
}

else if(c === '') {

alert('Lütfen Üye Soyadını Giriniz !');
}

if(! isFinite(parseInt(d , 10)) || (parseInt(d , 10) < 0) || (parseInt(d , 10) > 12) {

alert('Kayıt Ayı 1-12 Arası Bir Tamsayı Olmalıdır !');
}

else {

// Kaydı Yap !

klüpÜyesi[1] = KlüpÜyesi(a , b , c , d);// new Saklı Sözcüğüne Gerek Kalmadı !...

// Kaydı Bildir !

alert(klüpÜyesi[1].numara +  " " + klüpÜyesi[1].isim + " " + klüpÜyesi[1].soyad + klüpÜyesi[1].kayıtAyı + "\n (Kayıt Girişi Başarılı !");
}

return false;// çapa elementinin href niteliğinin etkisizleştirilmesi için...
}


function sil() {
yaz('nr' , '');

yaz('ad' , '');

yaz('soyad' , '');

yaz('ay' , '');

return false;// çapa Elementinin href niteliğinin etkisizleştirilmesi için...
}


function işlem(a,metot1,b,metot2){
var f = null, t = null;
f = document.getElementById('a');
f.onclick = metot1;

t = document.getElementById('b');
t.onclick = metot2;
}

// işlem() fonksiyonu bdelib.js program kitaplığına eklenmiştir.

function başlat() {
işlem('kayıtYap' , kayıtEkle , 'sil' , temizle);

+}

sayfaYüklendiktenSonraÇalıştır(başlat);

Bu programı çalıştırınız.

Uygulama örneğinde de görüldüğü gibi, bu programda yeni nesne sınıf örneğinin yaratılması için new saklı sözcüğü kullanımına gerek kalmamıştır. Bu yöntemin uygulanması programcının seçimine bağlıdır. Nesne örneklerinin üretilmesi için, nesne örneği üretme yeteneği olan her türlü veri giriş fonksiyonu güvenle kullanılabilir.

Hiyerarşik yapılanmanın sağlamlığı, veri giriş ve okuma fonksiyonların esnekliği özellikle geliştirme aşamasında önem taşır. Başlangıç aşamalarında önemli olan, programların iyi ve sorunsuz çalışmasıdır. Bir proje yaşayan bir organizma gibidir. Bir projenin yaşam süresi geniş bir sürece yayılır. . Bu süreç içinde geliştirme aşamasındaki genel amaçlı yönteemler, giderek özelleştirilebilir ve daha kullanıcı dostu haline getiririlebilir.

Sonuç olarak, JavaScript program dilinde, hiyerarşik sistemler, çok kolay çözümlenebilmektedir. Bu konuda incelemiş olduğumuz örnekler, konu için belirli bir bilgi düzeyi sağlamaya yeterli olduğu söylenebilir.

JavaScript program dilinde, hiyerarşik sistemler üzerine daha birçok çalışma bulunmaktadır. Bu çalışmalar literatürden izlenebilir. Genel olarak, JavaScript program dilinde, hiyerarşik sistemlerin oluşturulması konvansiyonel olarak ve en alışılmış şekliyle yukarıdaki örneklerde görülen yöntemler uygulanarak çözümlenmektedir. Diğer çalışmalar henüz öneriler düzeyindedir ve genel bir uygulamaları yoktur. Özel program kitaplıkları ve özel natasyonların kullanıldığı özel yöntemler ileride bakım aşamasında uyum sorunları ve bakım güçlükleri ortaya çıkarabilir. Ayrıca şimdiye kadar önerilmiş olan özel yöntemler, incelenen örneklerdeki yöntemlerden fazla bir avantaj sağlamamaktadırlar. Genel olarak bu bölümde incelenen metotlar, uygulamalarda kullanımı alışılmış olan metotlardır. Bu yöntemler, her türlü uygulama için yeterlidir. Bunun dışında, özel yöntemelerin kullanılması ancak kullanıcının yöntemi iyi bilmesi ile gerçekleşebilir. Yine de özel yöntemlerin, özel sorunları olabileceği daima gözönüne alınmalıdır.

15.3 - Çok Biçimlilik - Polimorfi

Polimorfi, bir metodun birden çok veri tipi ile çalışabilme yeteneğidir. Veri yapıları, benzer iç yapılanma da uygun oldukça polimorf metotlar oluşturulabilir. Polimorfinin amacı kod ekonomisi, yani az kodla çok iş yapma isteğidir. Aşağıda JavaScript kodları , görülen bir programda, polimorfik bir toplama metodu hem Elmalar hem de Armutlar sınıflarının toplam özelliklerinin değeri olarak kullanılmıştır. Bu programın bir uygulama sayfasında verdiği sonuç aşağıda görülmektedir:

...

function toplama() {

var sayı1 = 0, sayı2 = 0, toplam = 0;

if (this.elmaSayısı1 == undefined) {
sayı1 = this.armutSayısı1;
}

else {
sayı1 = this.elmaSayısı1;
}

if (this.elmaSayısı2 == undefined) {
sayı2 = this.armutSayısı2;
}

else {
sayı2 = this.elmaSayısı2;
}

toplam = sayı1 + sayı2;

return toplam;

}

function Elma() {

this.elmaSayısı1 = 12;
this.elmaSayısı2 = 23;
this.toplam = toplama;
}


function Armut() {

this.armutSayısı1 = 70;
this.armutSayısı2 = 30;
this.toplam = toplama;
}

var elmaSepeti = new Elma();

var armutSepeti = new Armut();

sonuçYaz('Elmaların Toplamı = ', elmaSepeti.toplam(), 'b15.3-uyg-1-sonuç-1');

sonuçYaz('Armutların Toplamı = ', armutSepeti.toplam(), 'b15.3-uyg-1-sonuç-2');
...
		

Program Sonucu :

Yukarıdaki uygulamada görüldüğü gibi, hem Elma(), hem de Armut() armut veri tipleri aynı polimorf toplama() metodundan yararlanarak toplamlarını hesaplamaktadırlar. Bu örnek polimorfinin tam bir örneğidir.

Yukarıdaki uygulamada , Elma(), ve Armut() veri tiplerinin alanlarının isimlendirilmesi, JavaScript iyi yazılım konvansiyonuna göre, amaçalarını belirtecek şekilde, ayırdedilebilir olarak adlandırılmışlardır. Bu da doğal olarak her iki veri tipinin alanlarını kullanmak zorunda olan polimorf toplama() metodunun yazılım yükünü arttırmaktadır. Eğer veri tiplerinin alanları benzer olarak adlandırılırsa, aşağıda verilmiş olan JavaScript programında olduğu gibi, polimorfi çok daha kolay gerçekleşebilmektedir. Bu programın ilişikli olduğu bir uygulama sayfasında verdiği sonuçlar aşağıda görülmektedir:

...

function toplama() {

return this.sayı1 + this.sayı2;

}


function Elma() {

this.sayı1 = 12;
this.sayı2 = 23;
this.toplam = toplama;
}


function Armut() {

this.sayı1 = 70;
this.sayı2= 30;
this.toplam = toplama;
}

var elmaSepeti = new Elma();

var armutSepeti = new Armut();

sonuçYaz('Elmaların Toplamı = ', elmaSepeti.toplam(), 'b15.3-uyg-2-sonuç-1');

sonuçYaz('Armutların Toplamı = ', armutSepeti.toplam(), 'b15.3-uyg-2-sonuç-2');
...
		

Program Sonucu :

Her iki uygulamanın da yazılımları incelendiğinde, ilk uygulamada veri tiplerinin alanları daha özel olarak adlandırılmış olduklarından polimorfik toplama() metpdunun her iki veri tipini de işleyebilmesi için, oldukça gelişkin ve hacımlı bir yazılıma gereksinme duyduğu, oysa ki, ikinci uygulamada veri tiplerinin alanları daha birbirleri ile uyumlu olarak adlandırıldığında, polimorfik toplama() metodunun yazılımın daha basitleştiği görülmektedir. Burada, gözetilmesi gereken ince ayar, alan aisimlerinin olanaklar ölçüsünde uyumlu fakat anlamını yitirmeyecek kadar özel olacak şekilde adlandırılmasıdır. İkinci uygulamanın bu koşulu sağlayabildiği söylenebilir.

Yukarıdaki uygulamalar, en basit bir toplama metodunun bile veri tiplerinin uyumsuzluğu nedeni ile uygulanmada zorlandığını açıkça göstermektedir. Polimorfiyi kolaylaştırmak için, veri tiplerinin anlamlarını belirtmeyecek şekilde genel olarak adlandırılmaları yine sakıncalı olmaktadır. Bu durumda, gerçek uygulamalarda polimorfik metotların uygulanabilmesi çok kolay olmamaktadır. Salt polimorfi uygulanabilmesi için içeriği karmaşık metotların yazılması da aslında bir kod ekonomisi yöntemi olan polimorfinin amacına uygun olmayacaktır. Eğer polimorfik metodun uygulanması için yazılım yükü aşırı artıyorsa, her veri tipi için ayrı bir metodun yazılması daha uygun olacaktır.

Valid XHTML 1.1