Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-12 Düzgün dizin yapısı

Bu yazı Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-11 Bileşenler, Composer ve JSON yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com

Buraya kadar composer kullanarak bileşenleri nasıl yükleyip erişebileceğimizi öğrendik. Şimdi sıra geldi onu kullanmaya. Bu yazıda PHPUnit anlatacağım, ancak herşeyden önce doğru dürüst bir yazılım paketi nasıl olur kısaca ona değineceğim. Adım adım ilerleyeceğiz. Eğer yoksa hemen GitHub hesabı kurmanızı öneriyorum. Kitabımda GitHub kurulumunu, nasıl üye olunacağını anlatmıştım.

Doğru Dürüst Dizin Yapısı

Doğru dürüst bir projemiz olsun istiyorsak dizin yapısına dikkat etmemiz gerekiyor. İster JavaScript, ister PHP, hangi dilde yazılım üretiyorsak üretelim, her zaman söylediğim gibi, bazı iyi pratiklere dikkat etmemiz lazım.

Her türlü projede en az iki tane dizinimizin olması şart: src ve tests. Src dizini adı üstünde source yani kaynak kodumuzun bulunduğu dizin olup, tests ise, PHPUnit veya başka bir test aracı kullanarak yazacağımız testlerin bulunacağı dizindir.

Örneğin güzel bir araç olan thephpleague/json-guard paketinin dizin yapısına bakalım.

Örnek paket

Bu paket üç dizinden oluşuyor.

  1. Docs: İsteğe bağlı olarak projemizin dokümanlarını tutabileceğimiz dizin.
  2. Src: Kesinlikle ve kesinlikle kaynak kodlarımızı tutmamız gereken dizin.
  3. Tests: Testlerimizi bulunduracağımız dizin.

Her açık ya da kapalı kaynaklı projede olması şart olan dosyalar da var. Bunlara da tek tek bakalım. Sonu md ile biten dosyalar markdown formatındadırlar. Bu formatı daha sonra detaylıca anlatacağım. Bir de paketlerimiz tüm dünya tarafından kullanılsın istiyorsak kesinlikle yazı içeren dosyalarımızı ingilizce yazalım.

  1. README.md: Her projede olması kesin şart olan dosya, projemizi kısaca tanıttığımız yer. Yazılımımızın yüklenmesi, nasıl kullanılacağı, kodun nasıl test edileceği gibi değişik yönergeleri de içerir. İyi README.md yazmak bir sanattır. O yüzden buna da detaylıca bir yazı ile değineceğim. (gerekli)
  2. LICENSE.md: Yazılımımızı hangi yazılım lisansı ile dağıttığımızı gösteren dosya. GPL olur, MIT olur ama ne olursa olsun, lisans bu dosyada durur.
  3. CHANGELOG.md: Projede yaptığımız değişiklikleri belirli bir formata göre yazdığımız dosya. (isteğe bağlı)
  4. CONTRIBUTING.md: Projenize katkı yapmak isteyen kişilere söylemek istediklerinizi buraya yazıyorsunuz. (isteğe bağlı)

Diğer dosyalar belirli araçları yönlendiren ayar dosyaları olduğundan onları daha sonra detaylıca anlatacağım. Ama kısaca değinmek gerekirse:

  1. .gitignore: Github aracının belli dosyaları görmezden gelmesini istediğimizde doldurmamız gereken dosya.
  2. .gitatrributes: Yine Github aracının belli dizin ve dosyalara bizim isteğimize göre özellikler atamasını sağlayan araç. Testlerin server’a indirilmemesini sağlıyor. (Not: Çok önemli. Asla, asla, asla testlerinizi production yani canlıda çalıştırmayın, test dosyalarını ve araçlarını canlıya almayın.)
  3. composer.json: composer paket yöneticisi için paketimizi tanıtmaya yarayan json dosyası.
  4. phpunit.xml.dist: PHPUnit aracını yönlendiren xml dosyası.
  5. .travis.yml, .scrutinizer.yml, CI yani sürekli entegrasyon araçlarını yönlendiren dosyalardır. Çok ileri bir konu, kitabın sonunda anlatıcam.
  6. .editorconfig, kullandığımız IDE yazılımının kod stilini ayarlayan dosyadır.

Şimdilik bu kadar. Bir sonraki yazıda test yazmayı anlatmayı düşünüyorum.

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-10 Sayfa Düzeni

Bu yazı Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-9 Şablonlar yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com

Alexey Brodovitch

Web sayfalarında veya basılı mecralarda, hiçbir zaman veriyi, yazıyı resmi olduğu gibi okuyucuya sunmuyoruz. İnsanların yazıları rahatça okuyabilmeleri için, ya da web sayfamızda kaybolmadan dolaşabilmeleri için sayfamızdaki verileri, belirli bir düzen kullanarak sayfaya yerleştirmemiz ve biçimlendirmemiz gerekiyor. Burada web tasarımı yapmanın ilkelerine girmeyeceğim, ancak merak ediyorsanız bu konuyu araştırabilirsiniz.

Örneğin dümdüz veriyi ekrana bastığımızda, bunlardan bir anlam çıkarmak neredeyse imkansızdır.

Arjantin Enflasyon Verisi

Bu yüzden bu verileri mesela grafikler kullanarak anlamlı hale getirmeye çalışırız.

Arjantin Enflasyon Grafiği

Yani amacımız sadece verilerimizin güzel gözükmesi değil, anlaşılabilir olması, uygulamamızın kolay kullanılabilmesi, okunaklı olması, belli amaçlar için aynı veriyi farklı şekilde görüntüleyebilmemiz (yeniden kullanılabilirlik) de aynı zamanda. Sayfa düzeni, veya herhangi bir şeyi tasarlarken, hatta kod yazarken kullanıcıların kolay kullanımını aklımızda tutmamız çok önemli. Ancak kolaylık, basitlik konusunda aklımızda tutmamız gereken diğer bir ilke ise şu:

Her şey olabildiğince basit olmalıdır, ama olabildiğinden daha basit olmamalıdır. Albert Einstein

Bu alıntıyı yapmamdaki sebep şu, siz işleri gelecekteki kullanıcılar kullanacak diye basitleştirmek ve mükemmelleştirmek için uğraşabilirsiniz. Uygulamanın, tasarımın ya da kodun, şurasını veya burasını iyileştirmek için günlerce aylarca uğraşabilirsiniz, ancak mükemmelleştirmeye çalışırken asıl amacı gözden kaçırabilirsiniz. Albert Einstein burada buna parmak basıyor. Bu hatayı 10 yıllık profesyonel yazılım hayatımda çok yaptım. Bu yüzden bu konuyu sürekli aklınızda tutmanızı, mükemmel değil, ama temiz, düzgün, çalışan ve daha sonra düzeltebileceğiniz incelikli prototipler üretmenizi öneririm.

Şimdi, dönelim tekniğe. Daha önceden Dekoratör tasarım deseninden bahsettik, yani bir veriyi alıp HTML etiketlerine sarmalayıp onu temiz bir web sayfası olarak kullanıcıya sunuyorduk. Bir önceki yazıda bunu yaptık. Şimdi veriyi değil de, bu ürettiğimiz bileşenleri de sarmalayabilecek bir yazılım yazalım. Yani Sayfa bileşeni, yan bilgi, ana bilgi, alt bilgi, form gibi bileşenleri barındırsın ve bunları gerektiğinde LEGO gibi birbirine ekleyip çıkarabilelim. Bu tasarım mantığına bileşen tabanlı geliştirme deniyor. Web Components Standardı, React.js, Vue.js bu ilkeyi uygulamalarımızda kullanmamızı sağlayan teknolojiler. Kitabın sonuna doğru bu teknolojilerden de detaylı olarak bahsedeceğim.

Önce daha önce şurada bahsettiğim bileşenleri tek tek listeleyelim.

  1. Head — Her sayfada olacak ama görünmeyecek, css gibi ihtiyaç duyduğumuz dosyaların listesini tutacağımız bileşen. <head> etiketi içinde yeralacak. Sayfanın başlığını belirlediğimiz <title> etiketi burada olacak.
  2. Üst Bilgi — Bütün sayfalarda değişmeyen, logo, üst navigasyon yani yön bulma linklerini, eğer varsa fb veya Twitter’daki gibi üst arama çubuğunu barındıracak, gerekiyorsa kullanıcının çıkış yapıp kendi profilini göreceği açılır menüleri tutacak bileşen. <header> etiketi ile tanımlanıyor.
  3. Yan bilgi — Opsiyonel bir bileşen, genellikle içinde olduğumuz program bileşeninin varsa iç bölümlerinde gezinmemize yarar, yani bu bölümleri link olarak listeler. Bazı programlarda, o an programı kullanan kullanıcı ile bilgileri de listeleyebiliyor.
  4. Ana bilgi — Buna main de deniyor ve <main> etiketi ile tanımlanıyor. Her sayfada bir adet bulunmak zorunda. Eğer bir sayfada önem olarak birbirine eşit farklı bölümler kullanacağım diyorsanız, <section> yani bölüm etiketini kullanacaksınız.
  5. Alt Bilgi — Yine bütün sayfalarda değişmeyecek olan alt bilgi kısmı. Genellikle, sayfaların copyright, telif, gizlilik ve kullanım sözleşmesi gibi sabit kısımları, varsa şirket adresi iletişim gibi bilgiler burada yer almalıdır. <footer> etiketi ile tanımlanır.
  6. Yeniden kullanılabilen bileşenler. Bunlara eleman / element ya da bileşen / component de denebiliyor. Lego gibi programlama amacında olduğumuzdan bu konunun mantığını anlamanız çok önemli. Bunu en kolay şu şekilde anlatabilirim. Örneğin, facebook’ta kendi duvarımızda yeni birşey paylaştığımızda ya da herhangi bir arkadaşımızın duvarında veya bir grupta birşey paylaşmak istediğimizde aynı form bileşeni ortaya çıkıyor ve biz bişiler yazıp gönder tuşuna basıyoruz.

Duvara bişiler yazarken

Gruba bişiler yazarken

İşte bu elemanı (ya da bileşeni) tekrar tekrar yazmamıza gerek yok, belli özelliklerini değiştirip, başka bir sayfada çağırıp kullanabilmemize yeniden kullanılabilirlik deniyor. İşte nesne yönelimli programlamanın bir diğer faydası da bu. Bu konuya da detaylıca sayfa kodunu yazmaya başladığımızda değineceğim.

Yeniden kullanılabilirlik, kod tekrarını önler

DictionaryView ve EntryView isimleriyle yarattığımız dosyaların birbirine benzediğine dikkat edin demiştim. Bir önceki yazıda kod tekrarını önlemekten bahsetmiştim. Şimdi gelin bu iki dosyadan kurtulalım. Program dizinimizin içinde View.php adlı bir dosya oluşturalım ve içeriğini şöyle değiştirelim:

<?php
namespace
MidoriKocak;

class View
{
private $data;

public function __construct()
{
$this->data = [];
}

public function set()
{
$args = func_num_args();
if ($args == 1 && is_array(func_get_arg(0))) {
$this->data = func_get_arg(0);
} elseif ($args == 2 && is_string(func_get_arg(0))) {
$this->data[func_get_arg(0)] = func_get_arg(1);
} else {
throw new InvalidArgumentException('Cannot set variable for View.');
}
}

public function render(string $filename)
{
extract($this->data);

ob_start();
require 'Template/' . $filename . '.php';
return ob_get_clean();
}
}

Her zaman yaptığım gibi kodu tek tek açıklamaya başlayalım. Daha önce her görünüm sınıfı için $this->dictionary veya $this->entry gibi değişkenler kullanarak, görünüm sınıfımıza veri enjekte ediyorduk. İki görünüm sınıfında da render, template ve __construct metodları değişken isimleri hariç aynıydı. Bunun yerine tek bir sınıf kullanıp işimizi halletmek için data adlı bir dizi değişkeni belirledik. __construct metodunda yani new diyerek sınıftan bir nesne yarattığımız anda, php yorumlayıcısı bizim için bu boş diziyi anında oluşturacak.

Asıl hinlik cinlik yaptığımız kısım set yani değişkenleri belirlediğimiz metod. Bu metod Görünüm yani View sınıfına göndermek istediğimiz, template dosyalarımızın kullanacağı değişkenleri enjekte etmemize yarıyor. Yani örneğin bir template yani şema dosyasında $renk adlı değişken tanımlamak ve bu değişkene “pembe” değeri vermek istersem bunu $view->set(‘renk’,’pembe’) diyerek yapabilirim. Peki birden fazla değişkeni aynı anda bir dizi kullanarak göndermek istersem? Bunun için de metoda sadece $view->set($array) ifadesini kullanarak $array ismindeki değişkeni göndereceğim. Peki metodu bu iki farklı parametreyle çağırmamızı sağlayacak olan yöntem ne? Birincisi opsiyonel parametreler kullanmak yani metodu şu şekilde tanımlamak:

public function set($value, $name = null)

Ancak bu şekilde metod ismi ve parametlerin isimlendirmesi anlamsız ve okunaksız oldu. Çünkü ikinci name yani isim parametresini opsiyonel tanımladığımda, $value adlı değişken dizi olmak zorunda. Ancak ben $value değişkenini sadece tek bir değişkenin değerini belirlemek için ifade ediyordum. Bunun yerine PHP de uzun süredir bulunan variadic yani parametlerinin sayısı değişebilen metod kullanmayı tercih ettim.

Bunu da metod çağırıldığında parametrelerin sayısını veren func_num_args() metodu ve sırasına göre metoda gönderilmiş parametrenin değerine değişken ismi kullanmadan erişmemizi sağlayan func_get_arg() yöntemlerini kullanarak sağladım. Bu tarz metodların, C ve C++ dilinde komut satırı uygulamaları yazılırken kullanıldığını görmüşsünüzdür. Çünkü tek bir program komut satırından çağırılırken, kaç parametrenin kaç değer alacağı önceden bilinmiyor. Örneğin diyelim ki composer adlı programı şu şekilde çağırabiliriz.

$> composer help --format=xml list

Burada help, programa verdiğimiz birinci parametre, format=xml ikinci parametre ve list de üçüncü parametre oluyor. Linux ortamına alışkın değilseniz, ya da Windows üzerinde cmd.exe kullanmadıysanız buraları anlamamanız gayet doğal. Sorun değil, öğrenmesi de zor değil. Tavsiye ederim.

Render metodu daha önceki görünüm sınıflarıyla aynı. Tek fark extract metodunu kullanmamız. buradaki extract($this->data) ifadesiyle, örneğin, data dizisi içinde ‘renk’=>’pembe’ değerinde bir eleman tanımlandıysa, buradaki değişkeni doğrudan echo $renk; diyerek kullanabiliyoruz mesela. Dikkat etmemiz gereken en önemli nokta, kullanıcıdan gelen hiçbir veriyi buraya temizlemeden sokuşturmamamız. Yani bu metoda parametre olarak girecek her tür kullanıcının form üzerinden girdiği veriye htmlspecialchars() metodunu kullanarak müdahele etmemiz gerekiyor yoksa 14–15 yaşındaki veletler sistemimizi hem çok pis hacklerler, hem de bizimle dalga geçerler. Bu konudan da güvenlik bölümüne vardığımızda detaylıca bahsedeceğim.

Şimdi app.php dosyasını açalım ve şu şekilde değiştirelim:

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';
require_once 'EntryInterface.php';
require_once 'Entry.php';
require_once 'View.php';

try {
$dictionary = new MidoriKocakDictionary("Nesne Yönelimli Programlama Sözlüğü");

$nesne = new MidoriKocakEntry('nesne', 'aklımızın dışındaki herşey');

$nesne->addValue('harika bişi');
$nesne->addValue('ingilizce object');

$şey = new MidoriKocakEntry('şey', 'ismi olmayan nesne');

$dictionary->addEntry($nesne);
$dictionary->addEntry($şey);

$entriesArray = $dictionary->getEntriesAsArray();

$entries = $dictionary->getEntries();

$dictionaryView = new MidoriKocakView();

$dictionaryView->set('dictionary', $dictionary);

echo $dictionaryView->render('dictionary');

} catch (Exception | Error $e) {
echo 'Error on line ' . $e->getLine() . ' in ' . $e->getFile()
. ': <b>' . $e->getMessage();
}

Dikkat ettiyseniz artık DictionaryView ve EntryView Dosyalarına ihtiyacımız kalmadı. Bunun yerine sadece tek bir sınıf kullandık.

App.php’yi web sunucumuzu kullanıp açtığımızda, tek bir görünüm sınıfının işleri başarıyla yerine getirdiğiniz göreceğiz.



Bu yazıda son olarak dikkat etmenizi istediğim bir satır da şu:

} catch (Exception | Error $e) {

Burada Error ifadesini de catch bloğuna ekledik ki, sadece exception tipinde değil, error tipinde de hataları yakalayalım. Eğer bunu yapmasaydık ve diyelim ki app.php içinde $dictionaryView->set(‘dictionary’, $dictionary); yazmayı unutsaydık, yani template dosyasında olmayan değişkenlere erişmeye çalışsaydık PHP yorumlayıcısı şu şekilde isyan bayrağını çekecekti.


Bunun yerine Error $e diyerek istisnaların yanında hataları da aynı şekilde yakalamak istediğimizi belirttik ve kullanıcının doğru düzgün bir hata mesajı görmesini sağladık:


Bu sayede hatanın nerde olduğunu kolayca bulup onu böcek gibi ezebiliriz. Şimdilik bu kadar. Bir sonraki yazıda bileşenleri birleştirip bir sayfa oluşturacağız (nihayet).

Bir sonraki yazıya şuradan ulaşabilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-9 Şablonlar

Bu yazı Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-8 -Web Arayüzü yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com


Bir önceki yazıda View yani görünüm sınıflarından bahsettik ve EntryView adında bir sınıf oluşturduk. Veriyi HTML kodlarıyla render metodunun içinde sardık ve sunumunu yaptık. Şimdi aynı render metodunu bir template yani şablon metodu kullanacak şekilde değiştirelim.

<?php

namespace
MidoriKocak;

class EntryView
{
private $entry;

public function __construct(EntryInterface $entry = null)
{
if ($entry !== null) {
$this->entry = $entry;
}
}

private function template(EntryInterface $entry)
{
$title = "<h3>" . $entry->getKey() . "</h3>";
$values = $entry->getValues();
$list = "";
foreach ($values as $value) {
$list .= "<li>" . $value . "</li>";
}

$result = "<p class='entry'>" . $title . "<ol class='values'>" . $list . "</ol>" . "</p>";

return $result;
}

public function setEntry(EntryInterface $entry)
{
$this->entry = $entry;
}

public function render()
{
if (!isset($this->entry)) {
throw new Exception('Cannot render without entry');
}

return $this->template($this->entry);
}
}

Bu kodda, önce private yani özel bir template metodu oluşturduk. Dikkat ettiyseniz Template metodu içindeki $this kullanmadık değişkenleri, $this ifadesinden kurtardık. Kodumuz bu haliyle de aynı şekilde çalışacak. Ancak bizim amacımız mümkün olduğunca PHP kodu ile HTML kodlarını birbirinden ayırmak. Bunun için içinde bulunduğumuz dizinde Template adında bir klasör oluşturalım ve bu dizinin içinde entry.php adında bir dosya oluşturalım. entry.php dosyasının içeriği şöyle olsun:

<p class="entry">
<h3><?= $entry->getKey() ?></h3>
<ol class="values">

<?php foreach ($entry->getValues() as $value): ?>

<li><?= $value ?></li>

<?php endforeach; ?>

</ol>
</p>

Not: Buraya böyle salak salak boşluklar koymamın sebebi, kısa foreach yani süslü parantez yerine iki nokta ile biten döngü kullandığımda, html dosyası olarak çıktısı alınacak php dosyasında, php etiketlerinin, indentasyonu, yani html etiketlerinin hizalanmasını bozması. Normalde, performans için, etiket dışındaki bütün bu boşluk ve yeni satır karakterlerini siliyoruz, ancak ben kitapta kod örneklerinin düzgün olması için bu boşlukları koydum.


Şimdi EntryView dosyasına dönüp template metodunun içeriğini şöyle değiştirelim:

private function template(EntryInterface $entry)
{
ob_start();
require 'Template/entry.php';
return ob_get_clean();
}

Yepyeni iki metod ile karşı karşıyayız. Output buffer yani ob_start() metodu, php’de ekrana basılacak olan herşeyi kaydetmeye yarar. Yani ob_start dediğimiz anda echo diyerek veya örneğin burada require diyerek çağırdığımız dosyanın metin içeriğini kamera gibi kaydetmeye başlıyoruz. ob_end_clean() metodu ise bu kaydettiğimiz şeyleri döndürür ve kaydettiğimiz output buffer denen zımbırtıyı siler. Bu sayede, tema dosyalarını kullanabilir, onları istediğimiz zaman ekrana istediğimiz değişkenlerle basabiliriz.


Şimdi, Template dizinimiz içinde dictionary.php isminde ikinci bir dosya oluşturalım. Bu yazacağımız DictionaryView yani Sözlük Görünüm sınıfımızın tema/şablon dosyası olacak. İçeriğini şu şekilde oluşturup kaydedelim:

<p class="dictionary">
<h2><?= $dictionary->getTitle() ?></h2>

<?php foreach ($dictionary->getEntries() as $entry): ?>

<p class="entry">
<h3><?= $entry->getKey() ?></h3>
<ol class="values">

<?php foreach ($entry->getValues() as $value): ?>

<li><?= $value ?></li>

<?php endforeach; ?>

</ol>
</p>

<?php endforeach; ?>

</p>

Daha sonra bir üst klasörde DictionaryView.php adlı bir dosya oluşturalım. İçi de şöyle olsun:

<?php

namespace
MidoriKocak;

class DictionaryView
{
private $dictionary;
private $entryView;

public function __construct(DictionaryInterface $dictionary)
{
$this->dictionary = $dictionary;
}

private function template(DictionaryInterface $dictionary)
{
ob_start();
require 'Template/dictionary.php';
return ob_get_clean();
}

public function render()
{
if (!isset($this->dictionary)) {
throw new Exception('Cannot render without dictionary');
}

return $this->template($this->dictionary);
}
}

Bişi dikkatinizi çekti mi? EntryView ve DictionaryView dosyaları birbirine benzemeye başladı. Kod tekrarını önlemek için ne yapıyorduk? Kodları birleştirip başka bir yere referans veriyorduk. Kalıtım konusuna geldiğimizde bu konuya detaylı olarak değineceğim.

Şimdi app.php dosyamızı, DictionaryView adlı yeni dosyamızı kullanacak şekilde değiştirelim.

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';
require_once 'EntryInterface.php';
require_once 'Entry.php';
require_once 'EntryView.php';
require_once 'DictionaryView.php';

try {
$dictionary = new MidoriKocakDictionary("Nesne Yönelimli Programlama Sözlüğü");

$nesne = new MidoriKocakEntry('nesne', 'aklımızın dışındaki herşey');

$nesne->addValue('harika bişi');
$nesne->addValue('ingilizce object');

$şey = new MidoriKocakEntry('şey', 'ismi olmayan nesne');

$dictionary->addEntry($nesne);
$dictionary->addEntry($şey);

$entriesArray = $dictionary->getEntriesAsArray();

$entries = $dictionary->getEntries();
$dictionaryView = new MidoriKocakDictionaryView($dictionary, new MidoriKocakEntryView());

echo $dictionaryView->render();

} catch (Exception $e) {
echo 'Error on line ' . $e->getLine() . ' in ' . $e->getFile()
. ': <b>' . $e->getMessage();
}

Herşeyi tamamladığımıza göre tarayıcımızı açalım:

Sözlük Görünümü

Gördüğümüz gibi, sözlüğümüzün başlığını ekrana bastık, daha sonra sözlüğün sahip olduğu girdilere göre verileri listelemeye başladık, her girdinin başlığını ve içlerindeki her açıklamayı ekrana bastık. Bunları yapmak için de tema dosyaları kullandık. Şimdi sayfamızın kaynağına bakalım.

Sayfa Kaynağı

İşte şimdi sayfamız birbirine girmiş etiketler yumağı yerine doğru dürüst bir HTML sayfasına benzedi. Peki bu düzgün formatlı bir html sayfası mı? Hayır, sadece dümdüz verileri listeliyoruz. Hala bir uygulamaya benzemiyor. Bir sonraki yazıda, tasarımını yaptığımız uygulamamızın sayfa düzenlerini nasıl oluşturup kullanacağımızı öğreneceğiz.

Bir sonraki yazıya buradan erişebilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-7 —Sınıfları Kullanmak ve API meselesi

Bu yazı daha önce yazdığım Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-6 yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com

Bu yazıya kadar, bir programı sınıflar kullanarak nasıl tasarlayacağımızı, nasıl temiz kod yazacağımızı, kodlarımızı nasıl hatalara karşı kontrol edeceğimizi, sınıflarımızın sorumluluklarının ne olacağını anlattık. Peki programımızı kim nasıl kullanacak? Sınıflarımızı yazdık ve app.php dosyası içinde de kullandık, ama son kullanıcı bu programı nasıl kullanacak? Bu yazıda bu konuyu detaylıca işleyeceğiz. Ayrıca programımıza arama, sıralama, üyelik gibi ek özellikler eklemek istediğimizde ne yapacağız? Bu meseleye de bu yazıda kısaca değineceğiz.

Kullanıcılar

Genel olarak programların amacı

Bu konuyu bu seride defalarca açıklamıştık ancak şimdi tıpkı başta sınıflarımızı tasarladığımızda yaptığımız gibi, programımızın nasıl çalışacağını ve amaçlarının ne olduğunu kısaca anlamamız gerekiyor ki, sınıflarımızı kullanacak program kodumuzu da nesne yönelimli bir şekilde tasarlayabilelim.

  1. Genellikle programların amacı kullanıcıdan istekleri ve girdiyi almak, bunu hatalı girdilere karşı doğruladıktan ve güvenlik açıklarına karşı temizledikten sonra işlemektir. Bu web uygulamalarında html dosyaları içindeki web formları aracılığı ile yapılır.
  2. Kullanıcı girdileri genellikle bir dosyaya veya veri tabanına kaydedilir. Verilere ne şekilde kaydedildiği genellikle programın mantığını tutan sınıfın sorumluluğunda değildir. (MVC konusunda bu kavramı detaylıca açıklayacağım.)
  3. Kullanıcı daha önce eklediği verilere erişmek ve görüntülemek isteyecektir. Yani program veri tabanından veriyi alıp, kullanıcıya, onun anlayabileceği şekilde göstermek zorundadır.

Daha önce nesneleri tasarlamayı anlatırken, nesnelerin bağımsız programlar gibi canlı ve kendi kendine yeten varlıklar olmaları gerektiğinden bahsetmiştik. Yani hiçbir nesne, mantıken başka bir nesneye göbekten bağlı, olmayacak. Bir diğer kural da bir nesne içinde başka bir nesneyi new ifadesi ile yaratmamak. Böyle bir kod bloku yazıyorsak, sınıfımızın diğer nesneye göbekten bağımlıdır ve o nesnede yapılacak herhangi bir değişiklik nesnemizin davranışını ve ondan beklentilerimizi bozacaktır. Daha iyi anlamak için şöyle bir örnek vereyim: Mesela bu yazıya eklediğim linkler üzerinde hiçbir kontrolüm yok. Eğer linkte bulunan yazı silinirse veya değişip saçma sapan bir siteye giderse, yazımda saçma sapan bir bilgiye yer vermiş olacağım. Bu konuya bağımlılık enjeksiyonu ve bağımlılık çevrimi (dependency injection ve dependency inversion) deniyor. Kabul, Türkçe’ye çevirince çok abuk oldu ama konuyu detaylıca anlattığımda buna da doğru dürüst bi karşılık bulmaya çalışırız. Solid ilkeleri ile ilgili bir kaynak: http://tarikkaygusuz.com/post/solid-prensipleri

Programdan beklentilerimiz ve arayüzler

Bu seride, sınıf ve program kavramlarını birbirinden ayrı düşünmemeye özen gösterdik. Bir sınıfı yazarken, yapabileceği işleri interface yani arayüzde tanımlamıştık. Daha sonra o sınıfı kullanan herhangi bir kod, sınıfın o arayüzde tanımlandığını bildiğinden erişebileceği ve kullanacağı public metotların neler olduğunu biliyordu. Herhangi bir programı web arayüzünden veya komut satırından kullandığımızda da aynı beklenti kalıplarına sahibiz. Örneğin, bir web uygulamasını veya sitesini açtığımızda, sol tarafta üstüste bir sürü link ile yapabileceğimiz işleri görebiliriz.


Kullanıcıların aşina oldukları arayüzleri programlarımızda kullanırsak, hem kolay kullanım hem de anlaşılabilirlik sağlamış oluruz.

Eğer Unix/Linux/MacOs/BSD terminaline, kabuğuna, komut satırına, ya da adı her ne boksa veya windows’taki cmd yazınca çıkan dos ortamına, powershell’e fln alışkınsanız, komut satırında herhangi bir komut ardından -h veya — help yazdığınızda, o programına hangi parametreleri girerek işlem yapacağınızı gösteren bir yardım listesiyle karşılaşacağınızı bilirsiniz.

Windows ortamında, cmd.exe’yi çalıştırıp dir /? yazarsanız, içinde bulunduğunuz dizindeki dosyaları gösteren dir komutunun yardım dokümanını görürsünüz.

Dos ortamında Dır komutunun yardımı

Unix ortamında çalışıyorsanız, herhangi bir komutun sonuna -h veya — help yazdığınızda aynı help dokümanıyla karşılaşmayı beklersiniz. Komutu yazan programcı, gıcık veya şerefsiz değilse genelde kullanıcının bu beklentisini tatmin etmeye çalışır.

Unix ortamında composer komutunun yardımı

İlk adım olarak bu “-h” ya da “ — help” parametresini bildiğinizde, kullanacağınız program hakkında hiçbir bilginiz olmasa dahi, programı nasıl kullanacağınızı size anlatacak bilgilere bu parametreyi kullanarak erişebilirsiniz.

Yenilikçi arayüzler

Yani bilgisayar programlarını yazarken kullanıcıların belirli davranış kalıplarına ve beklentilerine uyarsanız, kötü tasarımınız için küfür yemezsiniz. Tıpkı daha önce verdiğim araba arayüzü örneğinde olduğu gibi, vitesi tavana, direksiyonu vitesin olduğu yere, gaz pedallarını da direksiyonun üzerine koyabilirsiniz ama tabii ki koymamalısınız. Not: Bazı zamanlarda, aşırı yenilikçi kullanıcı arayüzleri yazmanız gerekebilir. Örneğin bir siteye girip uçak bileti almak yerine chat yapan yapay zeka bot programları ile konuşarak uçak bileti alabilirsiniz.

Chatbot arayüzü

Bu tarz yenilikçi arayüzler, yeni yeni kullanılmaya başlansalar da, bunlar için de ortak bir standart zamanla oturacaktır. En basitinden, herhangi bir chatbot’a merhaba dediğinizde merhaba demesini beklersiniz ki bu da bir arayüzdür ve beklentilerimizi tanımlar.

Yönlendirme — Routing

Şimdi genel olarak bir web uygulamasından beklentilerimiz meselesine dönelim. Şimdilik kullanıcı oturum açması parola girmesi kısmını geçeceğim. O konuyu kullanıcı yönetimi konusuna geldiğimizde detaylı olarak açıklayacağım. Bir web uygulamasını açmak için ilk olarak web tarayıcısına adres gireriz, ve genellikle uygulama neyi kaydediyorsa, ilk ekranında onların sıralı listesi gelir. Örneğin YouTube sitesini açtığımızda karşımıza sıralı, ya da belli başlı kategorilere ayrılmış videoların listesini görmek isteriz.

Youtube Anasayfa

Daha sonra mesela eğer video yüklemek istersek, video upload linkine tıklarız. Youtube örneğinde abuk subuk bir ikon kullanmışlar. Çok önemli ve dikkat etmemiz gereken ikinci beklentimiz de şu: Upload yani Video yükleme linkine tıkladığımız zaman, adres çubuğundaki adresin değişmesi. Görelim:

Video Yükleme

Gördüğümüz gibi adres https://youtube.com/upload olarak değişti.

Örneğin haber sitelerinde ya da wordpress bloglarında okunaklı adresler kullanıldığını görmüşsünüzdür. http://www.diken.com.tr sitesinde bir habere tıkladığımızda, tarayıcı şöyle bir adrese gider: http://www.diken.com.tr/galatasaray-hakem-hatalariyla-basladi-pazartesi-derbisiyle-bitirdi-ayricalik-degil-tarafsizlik-istiyoruz/


Ya da örnek bir uygulamada, kullanıcı uygulamayı açtığında doğrudan kaydedilen şeylerin listesini şu şekilde görebilir:

Ana Sayfa

Ya da örneğin Kullanıcı, uygulamada ayarları değiştirmek istiyorsa, settings yani ayarlar linkine tıklar ve karşısına şöyle bir görüntü gelir:

Ayarlar Sayfası

Kullanıcı ayarlar sayfasını açtığında karşısına hazırda ayarları görebileceği bir liste ve o ayarları değiştirebileceği bir form çıkmasını bekler.

Belirli adresleri girerek programda belirli bölümlerin çalışmasını sağlama işlemine, yönlendirme yani routing deniyor.

Uygulama Programlama Arayüzü — API

https://www.smartfile.com/infographic/api/

Diyelim ki sözlük uygulamamızın internet adresi, http://dictionary.mynameismidori.com olsun. Örneğin yygulamadaki varolan sözlükleri listelemek istersek, http://dictionary.mynameismidori.com/dictionaries adresine gireceğimizi biliriz. Kısaca bu linkleri inceleyelim

  1. /dictionaries: Sözlükleri listeleyece olan link
  2. /dictionaries/add: Yeni bir sözlük oluşturmamızı sağlayan formu karşımıza çıkarmalı.
  3. /dictionaries/12: 12 nolu id’ye sahip olan sözlüğü getirecek. Not: id dediğimiz numara, her varlık için eşsiz olan ve varlıkları birbirinden ayırmamızı sağlayan değişkendir. Örneğin, biz sözlük girdilerinde, girdi başlıklarını benzersiz olarak tanımladık. Yani ‘nesne’ adında başka bir girdi olmayacak. Bu sayede bir girdiye erişmek için anahtar olarak bu kelimeyi URL yani web adresi içinde kullanabiliriz.
  4. /dictionaries/12/edit: 12 numaralı sözlüğün, örneğin başlığını değiştirmemizi sağlayacak olan formu çıkaran adres.
  5. /dictionaries/12/delete: 12 numaralı sözlüğü silmemizi sağlayacak adres. Dikkat: Bu adrese erişildiğinde kullanıcıya emin misiniz diye bir bildirim yapılmalı ki, yanlışlıkla silme durumu olmasın.
  6. /dictionaries/12/entries: 12 nolu sözlüğe ait bütün başlıkların listesini getirmeli.
  7. /dictionaries/12/entries/add: 12 nolu sözlüğe ait yeni başlık eklememizi sağlayan formu göstermeli.
  8. /dictionaries/12/entries/nesne: İşte burada id, yani benzersiz anahtar olarak başlık kullandığımız için, linkimiz bu şekilde oluyor. Girdideki değerleri gösterecek. Bu sayfaya /dictionaries/12/entries/nesne/values adresiyle de erişebiliriz. Çünkü nesne girdisindeki açıklamaları zaten gösteren sayfa bu sayfa. Not: Peki ya add isminde çakışan bir başlık girilirse? Buna da dikkat etmemiz gerekiyor.
  9. /dictionaries/12/entries/nesne/edit: Nesne başlığına sahip olan girdinin başlığını değiştirmemizi sağlayan formu gösterecek.
  10. /dictionaries/12/entries/nesne/values/add: Nesne başlığına yeni açıklama eklememizi sağlayacak formu göstermeli.
  11. /dictionaries/12/entries/nesne/values/1: Nesne başlığında 1. sıradaki açıklamayı vermeli. Biz burada id, yani anahtar olarak değerin dizideki sırasını kullandık. Fakat doğru bir pratik olarak int yani tamsayı tipinde bir anahtar kullanmalıyız.
  12. /dictionaries/12/entries/nesne/values/1/edit: Nesne başlığında 1. sıradaki açıklamayı değiştiren formu göstermeli.
  13. /dictionaries/12/entries/nesne/values/1/delete: Nesne başlığında 1. sıradaki açıklamayı silecek olan adres.

Dikkat ettiyseniz, adresler belli deseni takip ediyor. Yani kaydettiğimiz varlığın çoğul ismi — anahtar değeri — add,edit,delete komutlarından bir tanesi. Eğer komut yoksa, hazırda kaydedilmiş varlıkları listeliyor veya anahtar varsa o varlığı ve bağlantılı varlıkları gösteriyor. Yani 12 numaralı sözlüğü açtığımızda, aynı zamanda aksini belirtmediysek, sözlükteki girdilerin listesini de görebilmeliyiz. Aslında bu listeleme işlemine de index deniyor. Yani /dictionaries/12/entries/ linki ile /dictionaries/12/entries/index linki aynı yere gidiyor.

İşte programı kullanmak için girdiğimiz bu adreslere programımızın Uygulama Programlama Arayüzü veya API’si deniyor. Daha bilimsel bir tanımlama verecek olursak:

Uygulama Programlama Arayüzü (UPA) [İngilizce: Application Programming Interface — API], işletim sisteminin, bir kütüphanenin veya bir servisin diğer programlara sağladığı fonksiyon ve sınıf kümesidir. Kaynak: http://www.emo.org.tr/ekler/1db5dd8fa2d87e7_ek.pdf

Başka bir kaynak da şurada: http://koddit.com/yazilim/api-nedir-ne-ise-yarar-orneklerle-inceleyelim/

API’lar sayesinde, örneğin, bir kullanıcıya ait twitter akışını, tıpkı o kullanıcının twitter profilini açmış gibi kendi sayfamızda gösterebiliyoruz. Bu konuyu farklı API’ları kullanmak bölümünde detaylıca anlatacağım.

Yani sınıflarımızı kullanacak program kodunu yazarken, ayrı ayrı index.php, add.php, edit.php gibi dosyalar yazıp tarayıcıyı bu sayfalara yönlendirmek yerine, kullanıcının isteklerini alıp yönlendiren bir program koduna ihtiyacımız olacak. Bunu da bir sonraki yazıda yapacağız.

Bir sonraki yazıya şuradan ulaşabilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-6— Girdi Sınıfı

Bu yazı daha önce yazdığım Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-5 yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com

Bir önceki yazıda girdi sınıfımızı kullanan sözlük sınıfımızı yazdık. Deneme/Yanılma yani Try/Catch bloklarını kullanarak hatalara dayanıklı kod yazmayı ve kod tekrarlarını önlemekten bahsettik. Bu yazıda Entry yani girdi sınıfımızı oluşturacağız.

Sözlük girdisi

Dictionary.php sınıfımızın bulunduğu dizinde Entry.php adlı bir dosya oluşturalım. Artık bir sınıfın aşağı yukarı nasıl olması gerektiğini biliyorsunuz. İçi boş sınıfımızı şu şekilde yazalım.

<?php

namespace
MidoriKocak;


class Entry implements EntryInterface
{
public function __construct(){}
public function setKey(string $key){}
public function getKey(): string{}
public function setValues(array $values){}
public function getValues(): array{}
public function getValue(int $order): string{}
public function setValue(int $order, string $newValue){}
public function addValue(string $value){}
public function deleteValue(int $order){}
}

Her sınıfın __construct metodu olması gerektiğine dikkat edelim. Diğer metodlar daha önce EntryInterface.php içinde isimlerini tanımladığımız metodlar olacak. Tek tek metotlarımızın içlerini doldurmaya başlamadan önce, sınıfa özel private, yani sadece sınıfın içinden erişebileceğimiz değişkenleri sınıfımızın koduna eklemeye başlayalım.

__construct yani sihirli yaratma metodundan önce değişkenleri sınıfa şu şekilde ekleyelim:

<?php

namespace
MidoriKocak;


class Entry implements EntryInterface
{
private $key;
private $values;

public function __construct(string $key, string $value)
{
$this->setKey($key);
$this->values = [];
array_push($this->values, $value);
}

Yaptıklarımızı her zaman yaptığım gibi tek tek açıklayayım:

  1. Sınıfımıza private yani özel tipinde, $key ve $values adlı iki değişken ekledik.
  2. $key burada metin tipinde girdinin başlığını tutacak. Her başlıkta olduğu gibi, boş olmayacak ve 70 karakterden uzun olmayacak. Buna benzer kontrolü, Dictionary.php dosyasında setTitle metodunda yapmıştık. Aynı metodu alıp biraz değiştirerek burada kullanacağız.
  3. $values değişkeni, girdinin sahip olduğu açıklamaları tutan diziyi içerecek.
  4. __construct metodu içinde parametre olarak $key ve $value adlı iki değer tanımladık ki, girdi sınıfımızı, kolaylık açısından, örneğin $entry = new Entry(‘nesne’, ‘harika bişi’); diyerek yaratabilelim.
  5. __construct sınıfımızın içine baktığımızda, tıpkı Dictionary.php dosyasındaki __construct metodundaki setTitle metodunda olduğu gibi, setKey adlı metod ile $key değişkenini belirliyoruz ve bu sayede $key değişkeninin boş olmadığını, yani “” değerinde bir metin olmadığını ve 70 karakterden kısa olduğundan emin olarak nesnemizi yaratıyoruz.
  6. $this->values = [] diyerek boş bir dizi oluşturuyoruz.
  7. array_push metodu ile aldığımız $value değerini doğrudan $values dizisinin içerisine, sıra numarası olmadan ekliyoruz. Daha sonra addValue metodunun içini doldurduğumuzda bu satırı değiştirmeliyiz. Önemli: Uymamız gereken önemli bir kural olarak değişkenlere her zaman, o değişkenleri değiştiren ilgili set/get veya add metodları ile erişmeli veya manipüle etmeliyiz.

Getter ve Setter metodlarını bankadaki veznedar gibi düşünebilirsiniz.

Erişici ve Değiştirici yani Setter ve Getter metotları

Sınıfımızın metodlarının içlerini doldurmaya devam edelim:

public function setKey(string $key)
{
try {
if (($key != "") && (strlen($key) <= 70)) {
$this->key = $key;
} else {
throw new InvalidArgumentException('Wrong key title.');
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

public function getKey(): string
{
return $this->key;
}

setKey ve getKey metodları, daha önce Dictionary.php yani sözlük sınıfımızdaki setTitle ve getTitle metodlarında olduğu gibi, değişkeni kurallarımıza uyarak değiştirmemizi ve erişimi kontrol etmemizi sağlıyorlar. Burada getKey metodu doğrudan değişkeni döndürmekte. Fakat daha sonra, örneğin, erişimi bir şekilde kontrol etmek istersek (Örneğin sadece yazının yazarının erişebildiği bir yazı gibi), bu metodu değiştirebiliriz. Aklımızda bulunsun. Yine try/catch blokları ile hata denetimi yaptık.

public function setValues(array $values)
{
try {
if (!empty($values)) {
$this->values = $values;
} else {
throw new InvalidArgumentException('Array cannot be empty.');
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

public function getValues(): array
{
return $this->values;
}

Tıpkı setKey ve getKey metotlarında olduğu gibi gelen değerleri kontrol ettik. Burada gelen dizinin boş olmamasını kontrol ediyoruz. Fakat, dizinin tek boyutlu ve her elemanının metin tipinde olduğunu tek tek kontrol etmemiz gerekirdi. Şimdilik kolaylık açısından bunu daha sonraya bırakalım.

private function isOrderInValues($order): bool
{
try {
if (!array_key_exists($order, $this->values)) {
throw new OutOfBoundsException('Cannot find entry in dictionary');
} else {
return true;
}
} catch (Exception $e) {
echo $e->getMessage();
}
return false;
}

Daha önce Dictionary.php sınıfında, bir anahtarın dizide olup olmadığını kontrol eden ve hata döndüren isKeyInEntries($key) metodu yazmıştık. Burada da isOrderInValues metodu ile aynı şeyi yapıyoruz ki olmayan bir değere erişim sağlamaya çalışan bir gerizekalı programımızı çökertmesin.

public function setValue(int $order, string $newValue)
{
if ($this->isOrderInValues($order)) {
$this->values[$order] = $newValue;
}
}

public function getValue(int $order): string
{
if ($this->isOrderInValues($order)) {
return $this->values[$order];
}
return "";
}

public function addValue(string $value)
{
array_push($this->values, $value);
}

public function deleteValue(int $order)
{
if ($this->isOrderInValues($order)) {
unset($this->values[$order]);
}
}

Kalan metodlarımızı da tek tek açıklayalım:

  1. setValue: Sıra numarası ile açıklamayı düzenleyen metot. Bu metot aslında istediğimiz değerleri sıra numarası ile erişip düzenlememize yarıyor. Yine isOrderInValues metodu ile o sıra numarasında değer olup olmadığını kontrol ettik.
  2. getValue: Sıra numarası ile açıklamayı döndürüyor.
  3. addValue: Sıra numarası kullanmadan doğrudan $values değişkeninin yani açıklamalar dizisinin sonuna istediğimiz değeri ekliyor.
  4. deleteValue: Sıra numarası girerek açıklamayı silmemizi sağlıyor.

AddValue ve setValue metotlarında, açıklamanın zaten ekli olup olmadığını da kontrol edebilirdik, ancak bunu da şimdilik kolaylık açısından geçiyorum. Arama kısmına geldiğimizde, bu konuyu detaylı olarak anlatacağım.


Girdi yani Entry sınıfımızı tanımlamayı bitirdik. Gelelim kodumuzu kullanacak kodu yazmaya. Aynı dizinde daha önceden yazdığımız app.php isimli dosyayı şu şekilde değiştirelim:

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';
require_once 'EntryInterface.php';
require_once 'Entry.php';

$dictionary = new MidoriKocakDictionary("Nesne Yönelimli Programlama Sözlüğü");

$nesne = new MidoriKocakEntry('nesne', 'aklımızın dışındaki herşey');

$nesne->addValue('harika bişi');
$nesne->addValue('ingilizce object');

$şey = new MidoriKocakEntry('şey', 'ismi olmayan nesne');

$dictionary->addEntry($nesne);
$dictionary->addEntry($şey);

$entries = $dictionary->getEntries();

print_r($entries);

Burada print_r metodu, dizileri insanların okuyacağı şekilde ekrana basan metoddur. Eğer herhangi bir sorun olmazsa, web sunucumuzdan app.php adlı dosyayı çağırdığımız zaman şöyle bir sonuçlar karşılaşacağız:

Ne kadar çok chrome extension yüklemişim yahu.

Sonuç olarak elimizde doğru dürüst çalışan tertemiz iki sınıfımız oldu.

Hata mesajlarımız anlaşılır ve açık olmalı. Bu nedir yani?

Peki hata durumunda ne olacak? app.php dosyasını şu şekilde değiştirelim:

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';
require_once 'EntryInterface.php';
require_once 'Entry.php';

$dictionary = new MidoriKocakDictionary("Nesne Yönelimli Programlama Sözlüğü");

$nesne = new MidoriKocakEntry('nesne', 'aklımızın dışındaki herşey');

$nesne->addValue('harika bişi');
$nesne->addValue('ingilizce object');

$şey = new MidoriKocakEntry('', 'ismi olmayan nesne');

$dictionary->addEntry($nesne);
$dictionary->addEntry($şey);

$entries = $dictionary->getEntries();

print_r($entries);

$şey değişkeninde oluşturduğumuz entry nesnesinin başlık bilgisini girmeyi unuttuk. Sonuç ne olacak? Görelim:


Dikkat. Eğer uncaught error gibi bir hata gördüysek hata try/catch bloklarımızın dışında meydana gelmiş ve biz önlem alamamışız demektir. İnceleyelim. Burada sorun, key değeri boş olmasına rağmen, setKey metodu içinde istisnayı yakaladığımız için kodun çalışmaya devam etmiş olması. Bunu şimdilik setKey metodunu şu şekilde değiştirerek çözelim:

public function setKey(string $key)
{
try {
if (($key != "") && (strlen($key) <= 70)) {
$this->key = $key;
} else {
throw new InvalidArgumentException('Wrong key title.');
}
} catch (Exception $e) {
echo $e->getMessage();
throw new Exception("Cannot create entry");
}
}

Sorunu şu anlık çözmek adına catch bloğu içinde kodu durduracak bir istisna fırlattık. Hata kodumuz şu şekilde değişti:


Gördüğümüz gibi kod çalışmaya devam etmedi ve hatanın olduğu yeri tamı tamına bize iletti.

Hata denetimi kimin sorumluluğunda?

Sorumluluk

Konuyu öğretmek açısından metotlarımızda try/catch bloklarını birlikte metotun içinde kullandık. Ancak, bu hatalara karşı önlem almak bizim sınıfımızın sorumluluğunda değil. Hatayı düzeltmek ve buna karşı önlem almak o kodu hatalı çalıştıran kişinin sorumluluğudur. Sınıf, sadece hatalı durumu belirtecek istisnayı fırlatır ve pisliğini temizle kardeşim der. Ayrıca, catch bloklarını tekrar tekrar metotlar içinde aynı şekilde kullandığımızı farkettiniz. Eğer bir yerde sık sık kod tekrarı oluyorsa, tekrarlanan kodun başka bir yere gitmesi ve oralardan erişilmesi gerekiyor. SOLID ilkelerinden henüz detaylıca bahsetmemiştim, ancak Single Responsibility Principle yani Tek Sorumluluk Prensibine göre her sınıfın iyi yapması gereken tek bir iş var. Bu tek sorumluluğa hata denetimi yapmak girebilir ama kodu kullanan kişinin hatasını temizlemek girmez. O zaman sınıfılarımızdaki try/catch bloklarını kaldıracak ve başka bir yere taşıyacağız. (Not: kitapta örnekleri baştan düzeltmek lazım.)

Yani tryb bloğu içindeki ifadeyi bırakalım, ve kalanını silelim. Örneğin setTitle metodu şöyleydi:

public function setKey(string $key)
{
try {
if (($key != "") && (strlen($key) <= 70)) {
$this->key = $key;
} else {
throw new InvalidArgumentException('Wrong key title.');
}
} catch (Exception $e) {
echo $e->getMessage();
throw new Exception("Cannot create entry");
}
}

Bunu şu şekilde değiştirelim:

public function setKey(string $key)
{
if (($key != "") && (strlen($key) <= 70)) {
$this->key = $key;
} else {
throw new InvalidArgumentException('Wrong key title.');
}
}

Gördüğümüz gibi kod artık sadece hata durumunda istisna fırlatıyor, ama bu istisnanın pisliğinin temizlenmesi artık kullanıcının sorumluluğunda. Entry.php ve Dictionary.php içindeki tüm try/catch bloklarını bu şekilde kaldırlarım. Yani try bloğu içindeki kodu dışarı taşıyalım, ve try/catch bloğunu yukarıdaki örnekteki gibi silelim.

Dictionary.php dosyamızın son hali şu şekilde olsun:

<?php

namespace
MidoriKocak;

class Dictionary implements DictionaryInterface
{
private $title;
private $entries;

public function __construct(string $title)
{
$this->setTitle($title);
$this->entries = [];
}

public function setTitle(string $title)
{
if (($title != "") && (strlen($title) <= 70)) {
$this->title = $title;
} else {
throw new InvalidArgumentException('Wrong title value.');
}
}

public function getTitle(): string
{
return $this->title;
}

public function getEntries(): array
{
$entries = [];
/* @var $entry EntryInterface */
foreach ($this->entries as $entry) {
$entries[$entry->getKey()] = $entry->getValues();
}
return $entries;
}

public function setEntries(array $entries)
{
if (!empty($entries)) {
$this->entries = $entries;
} else {
throw new InvalidArgumentException('Array cannot be empty.');
}
}

public function addEntry(EntryInterface $entry)
{
$key = $entry->getKey();
$this->entries[$key] = $entry;
}

private function isKeyInEntries($key) :bool
{
if (!array_key_exists($key, $this->entries)) {
throw new OutOfBoundsException('Cannot find entry in dictionary');
} else {
return true;
}
}

public function getEntry(string $key): EntryInterface
{
if ($this->isKeyInEntries($key)) {
return $this->entries[$key];
}
}

public function deleteEntry(string $key)
{
if ($this->isKeyInEntries($key)) {
unset($this->entries[$key]);
}
}
}

Entry.php dosyamızın son hali de şu şekilde:

<?php

namespace
MidoriKocak;


class Entry implements EntryInterface
{
private $key;
private $values;

public function __construct(string $key, string $value)
{
$this->setKey($key);
$this->values = [];
array_push($this->values, $value);
}

public function setKey(string $key)
{
if (($key != "") && (strlen($key) <= 70)) {
$this->key = $key;
} else {
throw new InvalidArgumentException('Wrong key title.');
}
}

public function getKey(): string
{
return $this->key;
}

public function setValues(array $values)
{
if (!empty($values)) {
$this->values = $values;
} else {
throw new InvalidArgumentException('Array cannot be empty.');
}
}

public function getValues(): array
{
return $this->values;
}

private function isOrderInValues($order)
{
if (!array_key_exists($order, $this->values)) {
throw new OutOfBoundsException('Cannot find entry in dictionary');
} else {
return true;
}
}

public function setValue(int $order, string $newValue)
{
if ($this->isOrderInValues($order)) {
$this->values[$order] = $newValue;
}
}

public function getValue(int $order): string
{
if ($this->isOrderInValues($order)) {
return $this->values[$order];
}
return "";
}

public function addValue(string $value)
{
array_push($this->values, $value);
}

public function deleteValue(int $order)
{
if ($this->isOrderInValues($order)) {
unset($this->values[$order]);
}
}
}

Şimdi app.php dosyamızı da şu şekilde değiştirelim:

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';
require_once 'EntryInterface.php';
require_once 'Entry.php';

try {
$dictionary = new MidoriKocakDictionary("Nesne Yönelimli Programlama Sözlüğü");

$nesne = new MidoriKocakEntry('nesne', 'aklımızın dışındaki herşey');

$nesne->addValue('harika bişi');
$nesne->addValue('ingilizce object');

$şey = new MidoriKocakEntry('', 'ismi olmayan nesne');

$dictionary->addEntry($nesne);
$dictionary->addEntry($şey);

$entries = $dictionary->getEntries();

print_r($entries);
} catch (Exception $e) {
echo 'Error on line '.$e->getLine().' in '.$e->getFile()
.': <b>'.$e->getMessage();
}

Gördüğümüz gibi tüm kullanıcı kodumuzu try/catch bloğu içinde aldık. Artık elimizde tek bir try/catch bloğu var. Üstelik catch bloğu içinde hata mesajımızı da değiştirdik. Bu sayede hatanın olduğu dosyayı, satırı ve mesajı aynı anda görebileceğiz. Eğer bunu metotlar içinde sürekli tekrarlanan try/catch blokları içinde yapsaydık aynı kodu sürekli yapıştırmamız gerekecekti. Unutmayın, eğer bir yerde kod tekrarı varsa, kötü tasarım vardır.


Şimdi hata kodumuzun nasıl göründüğüne bakalım:


Güzel görünüyor değil mi? Bu sayede kodumuzun neresinde hata olduğunu rahatça anlayıp değiştirebiliyoruz. Tek catch bloğu kullandığımız için, kodumuz ilk hatada duracak, ve kodun kalan kısmı da hatalı bir şekilde çalışmaya devam etmeyecek.

Şimdilik bu kadar. Bu yazıda entry yani girdi sınıfımızı tanımladık ve try/catch bloklarımızın kullanımını düzelttik. Bir sonraki yazıda uygulamamızı tamamlamaya devam edeceğiz.

Bir sonraki yazıya şuradan ulaşabilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-5 — Sınıfı inşa etmek


Bu yazı daha önce yazdığım Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-4 yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com

Önceki yazılarda nesne yönelimli programlama mantığını, sınıflarımızı nasıl oluşturacağımızı, tek sorumluluk prensibini, bilgi gizlemeyi, sihirli yaratıcı metotları kavramaya çalıştık. Bir önceki yazıda sadece metot isimlerini içeren arayüzler yani interface’ler yazdık. Önümüzde iki yol var:

  1. Harala gürele kullanıcıyı düşünmeden sınıfların içlerini doldurmaya başlamak.
  2. Ya da bu sınıfları kullanacak uygulamayı yazmak. Yani bu sınıfları uygulamayı yazarken test etmek ve çıkabilecek hatalara önceden önlem almak. Biz arayüz yazdığımız için kullanıcının kullanacağı kodları zaten belirtmiş olduk.

PHP’de test konusuna bu yazıda basitçe değineceğim. Çünkü kodumuzu insanlar kullanacak. Daha sonra phpUnit konusuna geldiğimizde detaylıca anlatacağım da. Bu insanların neye ihtiyaçları olduğunu, neler yapabileceklerini az çok tahmin edebiliyorsak, sınıflarımızın içlerini bu kullanıcıların yapacakları hatalara karşı dayanıklı bir şekilde doldurabiliriz. Tabii ki hiçbir kod parçası doğduğu anda hatalara karşı bağışıklık kazanmış değildir. Ama biz önceden tahmin edemeyeceğimiz durumlara olabileceğini aklımızda tutarak kodumuzu yazarsak, daha sonra kafamızı beton duvarlara vurmayız.


Sıradan vatandaş sınıfımızı nasıl kullanır?

Sıradan vatandaş sınıfımızı arayüzlerine bakarak kullanır. Interface yani arayüz, yazdığımız sınıf için aynı zamanda bir kullanım kılavuzu işlevi de görür aslında. Bu nedenle sınıfımızı arayüze uygun hale getirmekle işe başlayabiliriz.

Şimdi Dictionary.php dosyamızın içindeki her şeyi silelim ve şu kodu ekleyelim:

<?php

namespace
MidoriKocak;

class Dictionary implements DictionaryInterface
{
private $title;
private $entries;

public function __construct(string $title)
{
$this->setTitle($title);
$this->entries = [];
}

public function setTitle(string $title)
{
if (($title != "") && (strlen($title) <= 70)) {
$this->title = $title;
}
}
}

Burada yaptığımız bir kaç değişiklik var. implements kelimesini kullanarak, sınıfımızın DictionaryInterface.php içinde tanımladığımız sözlük arayüzünü kullandığını belirttik. İkinci yaptığımız değişiklik ise __construct metodunun içinde setTitle metodunu çağırdık ki, boş başlık gibi girdilerle, VALIDATION yani doğrulama kurallarımız ezilmesin. Her durumda geçerli olsun.

Doğrulama

Set metotlarının hiçbir şey döndürmediğine dikkat ettiniz mi? Zorunlu olmasa da bu bir kuraldır. Peki bir kullanıcı yanlış başlık girdiğinde bundan nasıl haberimiz olacak? Ya da yanlış başlık kullanılarak sözlük yaratılmasının önüne nasıl geçeceğiz? İşte burada PHP’deki harika programlama yapısı olan try/catch yani deneme/yanılma yapısı devreye giriyor.

Dene ve Yanıl yani Try/Catch

Kodu sürekli hatalara karşı kontrol edeceğiz.

Örneğin set metotlarımızda try/Catch yani deneme yanılma blokları kullanarak, abuk subuk değerler geldiğinde kullanıcıyı bu durumdan haberdar edeceğiz ve bu duruma göre önlem alacağız ki kullanıcı programı çökertmesin. Şimdi setTitle metodumuzu şu şekilde değiştirelim:

public function setTitle(string $title)
{
try {
if (($title != "") && (strlen($title) <= 70)) {
$this->title = $title;
} else {
throw new InvalidArgumentException("Wrong title value.");
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

Metodumuzu satır satır okuyalım.

  1. Try/Catch bloklarının dışında kod olmadığına dikkat edin.
  2. Try bloğunu açtığımızda, php yorumlayıcısından, burada olacak hataları, veya diğer bir değişle exception yani istisnai durumları gözetlemesini rica ediyoruz.
  3. if bloğundan sonra, else bloğu ekledik ki, hatalı bir girdi olduğunda throw diyerek, önceden tanımlı istisnalardan birini fırlatalım. Burada invalidArgument yani Hatalı parametre istisnası fırlattık. Bu sayede kodu kullanan kişi, coder, yani oraya hatalı bilgi giren gerizekalı, nerede hata yaptığını anlayacak ve önlemini alacak bi zahmet. İstisna içinde göstermek istediğimiz mesajı “Wrong title value.” diyerek belirttik.
  4. catch bloğu içerisinde Exception $e diyerek ne tipte hataya dikkat etmemiz gerektiğini tanımladık. echo $e->message ifadesiyle meydana gelen istisnanın mesajını ekrana bastık.

İstisna yani Excetion

Genellikle try/catch blokları bu şekilde yazılır. Ancak örneğin biz ekrana cart diye böyle birşey basarsak, bütün sitemizin ya da kullanıcıya döndürdüğümüz örneğin JSON formatındaki değerin yapısı bozulacak. (Not: JSON formatını daha sonra API bölümüne geldiğimizde detaylıca anlatacağım.) Daha sonra bu echo ifadesini değiştireceğiz, ama şimdilik böyle kalsın.

Tüm setter metotlarımızda try/catch mantığını kullanmalıyız. Bu sayede hatalı bir bilgi girişi olduğunda, nasıl bir hatayla karşılaştığımızı anlarız.

Aynı dizinde oluşturduğumuz app.php dosyasını şu şekilde değiştirelim.

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';

$dictionary = new MidoriKocakDictionary("Nesne Yönelimli Programlama Sözlüğü");

Daha sonra bu dosyada sınıfımızı kullanacak diğer kodları yazacağız. Dosyayı web sunucumuzdan çağıralım. Şöyle bir görüntü karşımıza gelecek:


Yani diyor ki, hani verdiğin sözler, vaadettiğin public metodlar nerde? O yüzden devam edelim ve DictionaryInterface.php dosyasında tanımladığımız arayüzdeki metotları Dictionary.php dosyası içinde tanımlamaya devam edelim. setTitle metodundan sonra şu metodları sınıfımıza ekleyelim. Korkmaya gerek yok, hepsini tek tek anlatacağım.

<?php

namespace
MidoriKocak;

class Dictionary implements DictionaryInterface
{
private $title;
private $entries;

public function __construct(string $title)
{
$this->setTitle($title);
$this->entries = [];
}

public function setTitle(string $title)
{
try {
if (($title != "") && (strlen($title) <= 70)) {
$this->title = $title;
} else {
throw new InvalidArgumentException('Wrong title value.');
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

public function getTitle(): string
{
return $this->title;
}

public function getEntries(): array
{
$entries = [];
foreach ($this->entries as $entry) {
$entries[$entry->getKey()] = $entry->getValues();
}
return $entries;
}

public function setEntries(array $entries)
{
try {
if (!empty($entries)) {
$this->entries = $entries;
} else {
throw new InvalidArgumentException('Array cannot be empty.');
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

public function addEntry(EntryInterface $entry)
{
$key = $entry->getKey();
$this->entries[$key] = $entry;
}

public function getEntry(string $key): EntryInterface
{
try {
if (array_key_exists($key, $this->entries)) {
return $this->entries[$key];
} else {
throw new OutOfBoundsException('Cannot find entry in dictionary');
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

public function deleteEntry(string $key)
{
try {
if (array_key_exists($key, $this->entries)) {
unset($this->entries[$key]);
} else {
throw new OutOfBoundsException('Cannot find entry in dictionary');
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

}

Şimdi içlerini doldurduğumuz metotlara tek tek gözatalım.

  1. getTitle: Pek açıklayacak birşey yok. Doğrudan sözlüğün başlığını metin tipinde döndürecek.
  2. addEntry: Sözlük sınıfındaki girdiler dizisine istediğimiz başlığı ekleyecek. Burada girdi başlığının boş olup olmamasıyla, ya da girdinin açıklaması olup olmamasıyla artık ilgilenmiyoruz. Bu konular Dictionary yani sözlük sınıfımızın sorumluluğunda değil. Çünkü bunları tek bir sınıfta halletmeye kalksaydık, sözlük sınıfı devasa bir Tanrı nesnesi (God Object) olurdu, ve tek başına her boku yapmaya çalışırdı. Bu metodun içinde $entry değişkeninde girdi Arayüzü sınıfını tanımlayan (implement eden) bir girdi nesnesi geleceğinden emin olduğumuz için, gelen nesnenin doğru dürüst verilere sahip olup olmadığını doğrulamamıza gerek yok. Zaten PHP yorumlayıcısı type hinting yani tip ipucu, yani metodun parametresinin tipini EntryInterface olarak tanımladığımız için, saçma sapan bir değere izin vermeyecek. Bu yüzden tekrar try/catch bloğunda bu değeri oluşabilecek hatalara karşı kontrol etmek için doğrulama yapmamıza gerek yok. Burada daha önce arayüzü açıklarken dediğimiz gibi, set yerine add yani ekle ifadesini kullandık. Çünkü set dediğimiz zaman, sınıfa ait tek bir değişkeni değiştirmeye çalıştığımız anlaşılıyor.
  3. setEntries: Yine burada da try/catch bloğu ile gönderdiğimiz dizinin boş olup olmadığını kontrol ettik. Aslında tek tek dizinin her elemanının EntryInterface tipinde olup olmadığını da kontrol etmemiz gerekiyordu. Ancak bu metodu daha sonra, hızlıca dosyadan sınıfı oluşturmak için kullanacağımız için bu kontrolü yapmayı veriyi kaydetme kısmına bırakıyorum.
  4. getEntries: EntryInterface tipinde objelere sahip olan sınıfın $entries dizisini döndürecek olan metot. Burada kolaylık açısından, diziyi metin içeren elemanlar olarak döndürelim.
  5. getEntry: Burada try/catch bloğu ile doğrulama yaptık çünkü sorulan key yani girdi başlığı değerinin dizi içerisinde olup olmadığını kontrol etmek istiyoruz. İstisna olarak OutOfBoundsException fırlattık. Bu istisna bir dizide olmayan değere işaret ettiğimizi gösteriyor.
  6. deleteEntry: Tıpkı getEntry metodunda olduğu gibi $key değerini hatalara karşı kontrol ettik. Kod tekrarı yaptığımıza dikkat edin.

Sözlük programımızı yazmaya devam ediyoruz.

Kod tekrarlarını önlemek

Şahsen yapılan kod tekrarlarına uyuz olan bir insan olduğum ve kopyalayıp yapıştırılan kod öbekleri, kodumuzu saçma bi şekilde şişmanlatacağından tekrarlanan kodu ayrı bir metot haline getireceğim.

Şimdi en sondaki getEntry ve deleteEntry metotlarını silelim ve şu kodu ekleyelim:

private function isKeyInEntries($key) :bool
{
try {
if (!array_key_exists($key, $this->entries)) {
throw new OutOfBoundsException('Cannot find entry in dictionary');
} else {
return true;
}
} catch (Exception $e) {
echo $e->getMessage();
}
return false;
}

public function getEntry(string $key): EntryInterface
{
if ($this->isKeyInEntries($key)) {
return $this->entries[$key];
}
}

public function deleteEntry(string $key)
{
if ($this->isKeyInEntries($key)) {
unset($this->entries[$key]);
}
}

Gördüğünüz gibi isKeyInEntries adında bir metod yazdık. :bool diyerek kesinlikle bool yani true false, yani doğru yanlış tipinde bir değişken döndürmesi gerektiğini belirttik. Metodun sonuna return false koyduk ki, başta belirttiğimiz return sözüne uyalım. Eğer bunu buraya koymazsak, kullandığımız ide veya phpmd, phpcs gibi kod kontrol araçları, neden metod kodunda birşey döndürmüyorsun diyebilir. if bloğu içinde return ifadesi olması yeterli değil. Kod her durumda eğer birşey döndürmeyi taahüt ettiyse o değer tipinde bir değişkeni döndürmeli. (Not: Null Object Pattern kısmında bu konuyu detaylıca anlatacağım.)

isBilmemne şeklinde yazilan metodlar genellikle kontrol metodlarıdır ve true veya false döndürürler. Bu try/catch bloğunda yaptığımız kontrol işini bizim için yapacak olan metot. private diyerek bu metodun sadece sınıf içerisinden erişilebileceğini belirttik. Bu sayede programı kullanan herhangi bir kimsenin bu metodun varlığından haberi olmayacak. Bu şekilde metotlar içinde kullandığınız, zırt pırt tekrar eden kod bloklarını ayrı bir private metot haline getirirsek, sınıflarımızı önemli ölçüde fit bir hale getirmiş oluruz.

Şimdi örneğin hatalı bir durumda ne olacağını görmek için, app.php dosyamızı şu şekilde değiştirelim:

<?php

require_once 'DictionaryInterface.php'
;
require_once 'Dictionary.php';

$dictionary = new MidoriKocakDictionary("");
$dictionary->setTitle("Doğru başlık");
$dictionary->getTitle();

app.php dosyasını web sunucumuzdan çağırdığımızda şöyle bir şey karşımıza çıkmalı:

Yakalanmış istisna durumu

Gördüğümüz gibi, kodumuz hatalı girdiyi yakaladı ve php yorumlayıcısı kodun kalan kısmını çalıştırmadı. Bu sayede ne çeşit bir hatayla karşılaştığımızı anladık. Daha sonra bu hata mesajını da özelleştirmeyi göstereceğim.

Şimdilik bu kadar. Bir sonraki yazıda Girdi yani Entry sınıfımızı tanımlayacağız. Sevgiyle kalın.

Bir sonraki yazıya şuradan ulaşabilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-4


Bu yazı daha önce yazdığım Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş-3 yazısının devamıdır. Önce onu okumanızı öneririm.

View at Medium.com

Bir önceki iki yazıda şu soruları sormuş ve kısmen cevap vermiştik:

  1. Eklemek istediğimiz başlık sözlükte yoksa ve çağırdıysak bu sorunu bildirim göstermeden nasıl hallederiz?
  2. Başlık zaten varsa ve değiştirmek istemiyorsak, aynı başlığa yeni bir açıklama değerini nasıl ekleriz?
  3. Bir başlığı silmek ya da düzenlemek istediğimizde ve başlıkta birden fazla açıklama varsa, tüm açıklamalara mı etki edeceğiz yoksa sadece birine mi?
  4. Bir başlığa, tarih bilgisini nasıl girebiliriz? Bu tarih bilgisine dayanarak nasıl sıralama işlemi yapabiliriz?
  5. Arama, filtreleme işlerini nasıl yapacağız?

Önce, bir önceki yazıda spagetti usulüyle bir takım değişiklikler yapmıştık. Bu değişiklikleri Dictionary.php dosyasındaki sınıfa taşıyarak işe başlayabiliriz.


Dictionary.php dosyamızın içine şu metodu ekleyelim:

public function getEntry(string $key): string
{
if (array_key_exists($key, $this->entries)) {
return $this->entries[$key];
}
}

2. soruyla devam edelim. Aynı başlığa birden fazla değer eklemek istediğimizde ne yapmamız gerek? Burada Dictionary sınıfımızın davranışını gözle görülür şekilde değiştirmemiz gerekecek. Yani, Dictionary sınıfı, artık kendisinden bir başlık talep ettiğimizde metin yani string değeri yerine bize bir dizi değeri döndürmeli.

Sınıfları görevlerine göre parçalamak


Dikkat: Dictionary sınıfının sorumlulukları artıyor! Sözlük yani Dictionary sınıfı sadece verilen başlıklara karşılık açıklamaları yerine getirmek sorumluluğuna sahipti. Şimdi bir sözlük girdisinin nasıl yönetileceğine de el atmaya başladı. Bu nedenle, sınıflarımızı temiz ve düzenli tutmak istiyorsak, tek sorumluluk yani single responsibility prensibine göre sınıfımızı parçalamamız gerekiyor. Henüz tasarım ve prototip aşamasında olduğumuzdan, sınıfımızın davranışını, arayüzünü ve kodlarını istediğimiz gibi değiştirebiliriz. Ancak örneğin milyonlarca kullanıcısı olan, koda kafamıza göre müdahele etmemizin kabusa yolaçacağı durumlar profesyonel hayatımızda zırt pırt karşımıza çıkacak. İkinci aklımızda tutmamız gerek prensip Open-Closed yani Açık-Kapalı prensibi. Bu prensibe göre,

Sınıflar değişime kapalı, gelişime açık olmalıdırlar.

Üstte bahsettiğim sorunu çözmenin, farklı yöntemleri mevcut ki bu yöntemleri kullanmamız sayesinde Amerikayı yeniden keşfetmemize veya tekerleği bir daha icat etmemize gerek kalmasın. Bu prensibi nasıl kullanacağımıza daha sonra detaylıca değineceğim. Şimdilik sınıfımızı parçalamakla işe başlayalım. Sözlük sınıfımızı parçalayıp yeni bir girdi sınıfı hazırlayacağız. Burada özellikle dikkat etmemiz gerek nokta, sınıfların birbirlerinden bağımsız, tek başına yaşayabilen canlılar gibi olmaları. Şimdi tekrar sınıflarımızın sorumluluklarını güncelleyelim.

Programımız lego gibi sökülüp takılabilen parçalardan oluşmalı

Sözlük sınıfının sorumlulukları

  1. Farklı başlıklara sahip olan sözlükler yaratmak, başlığı güncelleyip değiştirebilmek.
  2. Arama, sıralama, güncelleme, filtreleme işlerini yapmak.
  3. Sıralı olan nesne verisini, örneğin metin, word veya json formatında kullanıcıya göndermek.
  4. Bir girdiği listeden silmek, yeni bir girdiyi listeye eklemek. Dikkat, girdiyi güncellemek, sözlük sınıfını alakadar etmiyor. Aynı başlıkta hali hazırda başka bir girdi listede mevcutsa, hata vermek. Çünkü girdi başlıkları benzersiz olacak. Bazı sözlüklerde aynı başlıkla farklı girdiler eklenebiliyor. Ancak bizim sözlüğümüzde girdiler 1. açıklama 2. açıklama diye ilerleyecekler.

Girdi Örneği

Girdi sınıfının sorumlulukları

  1. Yeni bir başlık ve açıklama ile bir girdi yaratmak.
  2. Girdinin başlığını ve açıklamalarını değiştirmek.
  3. Girdiye yeni açıklama girmek.
  4. Girdiyi silmek. Silerken açıklamalar dizisini boşaltmak. Eğer girdinin tüm açıklamaları silindiyse, girdinin kendisini silmek.
  5. Sırası bilinen açıklamayı silmek, değiştirmek.


Tembel yazılımcılar için arayüz yani interface kavramı

Daha önce arayüz kavramından, otomobil örneği ile bahsetmiştik. Arayüz sınıfımızın nasıl kullanıldığını dünyaya tanıtan bir programlama yapısı. Arayüzler, içi boş metodların bir listesinden başka bir şey değil aslında. Arayüzlerin içinde metodun kodundan ziyade metodun imzasını, yani aldığı parametreleri, paramtere tipini, döndüreceği değerin tipini tanımlıyoruz.

Bizi sadece dışarıdaki butonlar fln ilgilendiriyor, bu butonlarla cihazı kullanıyoruz. İçindeki elektronik hedelerle alakamız yok.

Arayüz tanımlamak aynı zamanda, kodun nasıl çalışacağını yazmaya girişmeden önce bize genel olarak program yapısını tasarlama fırsatı veriyor. Peki PHP’de arayüz nasıl tanımlanıyor? Öncelikle arayüz yazarken arayüz adı ve sonun Interface yazmayı alışkanlık haline getirelim. Böyle yapmak zorunlu değeil ama şıklık, düzenlilik açısından şart. Bunun gibi iyi pratiklere baştan sahip olmaya çalışırsanız, daha sonra sorun yaşamazsınız. Şimdi ilk arayüzümüzü yazmaya başlayalım.

Girdi Arayüzü yani EntryInterface

<?php

namespace
MidoriKocak;


interface EntryInterface
{
function setKey(string $key);
function getKey(): string;
function setValues(array $values);
function getValues(): array;
function getValue(int $order): string;
function setValue(int $order, string $newValue);
function addValue(string $value);
function deleteValue(int $order);
}

Tıpkı sınıflarda olduğu gibi interface yani arayüzlerin de ait oldukları isim alanları yani namespaceler var. Dosyanın başına içinde bulunduğumuz namespace’yi belirttik. Aslında doğrudan Entry sınıfını yazabilirdim ama metodların içerisini doldurmaya üşendiğim için interface yazmayı tarcih ettim. Sınıfları parçalarken gaza gelip atomu parçalamaya kadar gidebiliriz ama başımıza büyük bela alırız.

O kadar çok berbat kod gördüm ki, artık dünyaya ben de böyle bakıyorum.

Einstein’in şöyle bir lafı var:

Everything should be made as simple as possible, but not simpler. Albert Einstein

Yani meali, “Herşey olabildiğince basit yapılmalıdır, ancak bundan daha basit olmamalıdır.” O yüzden şimdilik başta karar verdiğimiz görev ve sorumlulukların dışında nesneler oluşturmuyoruz ki proje bitsin.

Arayüzü satır satır okumaya devam edelim.

  1. setKey: metin olarak bir başlık alacak. Girdinin başlığını belirliycek.
  2. getKey: başlığı metin olarak döndürecek.
  3. setValues: girdi içindeki açıklama listesini doğrudan değiştirmemizi sağlayacak. Şimdi farkettiğim üzere şimdilik bu metoda ihtiyacımız yok. Basitlik, bilgi gizleme ve güvenlik açısından silebiliriz. Ne kadar az metod o kadar kolay kullanım çünkü.
  4. getValues: girdiye ait başlıkları doğrudan dizi olarak döndüren metod.
  5. getValue: değerine erişmek istediğimiz açıklamaya sırasını belirterek erişmemizi sağlayan metod.
  6. setValue: değerine değiştirmek istediğimiz açıklamaya sırasını belirterek değiştirmemizi sağlayan metod.
  7. addValue: Sıra belirtmeden, doğrudan açıklamalar dizisine açıklama eklememizi sağlayan metod. Kolay kullanım için.
  8. deleteValue: Sıra belirterek istediğimiz açıklama değerini silmemizi sağlayan metod.

Gördüğümüz gibi, elimizde bağımsız, başka bir sınıfla alakası olmayan, kendi başına bir program gibi kullanabileceğimiz bir sınıf arayüzü oluştu.

Sözlük arayüzü yani DictionaryInterface

Şimdi Sözlük sınıfına baştan yeni bir arayüz yazalım ve bu arayüz de girdileri yönetmek için bu girdi arayüzünü kullansın.

<?php

namespace
MidoriKocak;

interface DictionaryInterface
{
function setTitle(string $title);
function getTitle(): string;
function setEntries(array $array);
function getEntries(): array;
function addEntry(EntryInterface $entry);
function getEntry(string $key): EntryInterface;
function deleteEntry(string $key);
}

Bu arayüzü de satır satır inceleyelim.

  1. setTitle: Oluşturacağımız sözlüğün başlık değişkenini değiştirmemizi, metin tipinde bir parametre alarak sağlayan metod. (set metodlarının hiçbirşey döndürmediğine dikkat edin. Set metodlarında hata olup olmadığını nasıl anlayacağız peki? Buna da hata denetimi konusuna geldiğimizde detaylıca değineceğim.)
  2. getTitle: Başlık değişkenini metin olarak döndürmek zorunda olan metod.
  3. addEntry: Sözlüğümüze entry yani girdi sınıfından bir nesneyi eklememizi sağlar. Set yerine add yani ekle ifadesini kullandık ki, sınıfta birden fazla entry yani girdi tutulduğu metodun adından anlaşılsın.
  4. getEntry: (metin tipinde $key) degeri girerek basliga erismemizi saglar.
  5. setEntries: Bu da sözlük sınıfında verileri tuttuğumuz diziyi değiştirmemizi sağlayan metod. Kullanırken dikkatli olmalı ve diziyi direk entries yani girdiler değişkenine eklememeli, tek tek girdiler kurallara uyuyor mu kontrol ederek sağlam verileri diziye eklemeliyiz.
  6. getEntries: Varolan verileri dizi şeklinde döndüren metod. Girdi sınıfından nesneler içeren bir dizi döndürecek.
  7. deleteEntry: Sözlükten adını belirttiğimiz girdiyi silen metod. Eğer bir girdinin hiç açıklaması yoksa, bu başlık da otomatik olarak silinmeli. Ancak buna daha sonra dikkat edeceğiz.

Minik minik nesneler

Şimdilik bu kadar. Bir sonraki yazıda bu arayüzlerin içini nasıl dolduracağımıza ve kodu nasıl kullanıp test edeceğimize bakacağız.

Sevgiyle kalın.

Bir sonraki yazıya buradan ulaşabilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Nesne Yönelimli Sistemler Için Soyut Bir Nesne Modeli

Alan Snyder Yazılım Teknolojisi Laboratuvarı HPL-90–22 Nisan 1990 Çeviri: Midori Koçak — mtkocak (at) gmail (dot) com 30.12.2016


Anahtar kelimeler: nesne-yönelimli programlama, nesne yönelimli sistemler, nesne modelleri, veri modelleri, dağıtık sistemler, nesne yönetimi

Bu rapor, nesne yönelimli sistemler için soyut bir nesne modeli tanımlamaktadır. Soyut nesne modeli temel kavramlar ve terminolojinin organize bir şekilde sunulmasını sağlamaktadır. (Soyut nesne modeli) dağıtık bir nesne yönetimi altyapısı üzerine kurulmuş uygulamalar tarafından görüldüğü şekilde kısmi bir hesaplama modeli tanımlamaktadır. Amacı, nesne sistemlerinin temel özelliklerini bünyesinde toplayan genel bir taslak sunmaktır. Bu çerçevede, genel modelin detaylandırılması (rafine edilmesi) ve doldurulması (genel modele ait belirli varlıkların tanımlanması) yoluyla, birçok belirli nesne modelini tanımlamak mümkün olmalıdır. Soyut model, Nesne Yönetim Grubu’nun kullanımı için, önerilen nesne teknolojilerini talep etmek, açıklamak ve değerlendirmek için ortak bir kavramsal çerçeve olarak geliştirilmiştir.

© Telif Hakkı Hewlett-Packard Company 1990

Önsöz

Bu rapor, Nesne Yönetim Grubunun teknik komitesi tarafından kullanılmak üzere hazırlanmıştır. (Rapor) OMG (çn. NYG olarak adlandırılacaktır) teknik komitesine, gelişen NYG standardının durumunu tanımlayan daha büyük bir belgenin parçası olması önerilmiştir. Bu rapor, OMG’nin resmi bir belgesi değildir. NYG standardının durumu hakkında daha fazla bilgi için, lütfen Nesne Yönetimi Grubuna başvurunuz. Nesne Yönetimi Grubu, Framingham Kurumsal Merkezi, 492 Old Connecticut Path, Framingham, Massachusetts 01701.

Teşekkürler

Bu rapor, Nesne Yönetim Grubunun teknik komitesinin bir faaliyeti olarak gerçekleştirilen çalışmaları belgelemektedir. Jeff Eastman, Jon Gustafson, Brian McBride, Ian Thomas, Jan te Kiefte, Lee Scheffler, Rod Bark, Pete Showman, Dennis Tenney ve Tom Allen gibi birçok insandan gelen görüşmelerden ve geribildirimden yararlanılmıştır. Özellikle, Bill Kent ile nesne arayüzleri, nesne kimliği ve nesne durumu konularında yapılan kapsamlı tartışmalardan yararlanılmıştır. Bill, genelleştirilmiş nesne modelini (çn. rapora) dahil etmek için ilk mücadeleye başlamamı sağladı ve olayları daha dikkatli ve açık bir şekilde açıklamam için birçok kez beni zorladı. Bill’in bu belgeye katkısıim, tüm konularda fikir birliğine vardığımz gibi algılanmamalıdır. Son olarak, bu çalışma Alain Couder tarafından başlatılan HP “nesne görev gücü’nün” daha önceki çalışmasının bir sonucudur.

Giriş

NYG nesne modeli, NYG nesne kavramlarının ve terminolojisinin organize bir sunumunu sağlamaktadır. Nesne modeli, NYG uyumlu uygulamaların ve son kullanıcı uygulamalarının karşılaştığı hesaplama modelini kısmen tanımlamaktadır. NYG nesne modelinin amacı, NYG tarafından önerilen teknolojiler için kavramsal bir çerçeve tanımlamak ve özellikle belirli teknolojileri önermek ve benimsemek için yapılacak temel tasarım seçimlerini motive etmektir.

NYG nesne modeli, bir NYG sisteminin bileşenlerini veya arabirimlerini tanımlamamaktadır. Nesne modeli, NYG uygulamalarının yapısını da tanımlamaz. Nesne modeli, belirli nesneleri, belirli türde nesneleri veya nesnelere özel arayüzleri tanımlamaz. Bu konular NYG referans modeli tarafından ele alınmaktadır.

Önerilen herhangi bir NYG teknolojisinin burada, modeli detaylı olarak anlatması ve oluşturması beklenmektedir. Modelin ayrıntılandırmak, örneğin talep öz niteliklerinin biçimini veya türleri belirlemek için kullanılan dili tanımlayarak daha belirli hale getirilmesi anlamına gelmektedir. Modeli doldurmak, model tarafından tanımlanan belirli varlık örneklerini, örneğin belirli nesneleri, belirli işlemleri veya belirli türleri ortaya koymak demektir.

Bu nesne modelinin bir amacı da, önerilen teknolojilerin olası modellerine gereksiz kısıtlamalar getirmekten kaçınmaktır. NYG nesne modelinde somutlaştırılan gereklilikler, nesne teknolojisi kavramı için “gerekli” kabul edilenlerdir.

Nesne sistemlerinin temel karakteristiği, nesne istemcileri tarafından görülen nesnelerin semantiği ile bu semantiklerin varolan veri gösterimleri ve çalıştırılabilir kod açısından uygulanımları arasındaki ayrımdır. Nesne semantiği, nesne oluşturma ve nesne kimliği, talep ve işlemler, türler ve imzalar gibi kavramları içerir. Nesne uygulanımı, yöntemler, veri yapıları, sınıflar (uygulanım tanımları gibi) ve uygulama kalıtımı gibi kavramları içermektedir.

Nesne modeli ilk önce nesne semantiği ile ilgili kavramları tanımlar ve ondan sonra nesne uygulanımı ile ilgili kavramları açıklar. Nesne semantiği istemcilere görünür olduğundan, nesne modeli, nesne semantiği kavramlarını tanımlamada en belirgin ve kural belirleyici kavramdır. Nesnenin uygulanımı ile ilgili tartışmalar daha fikir vericidir; çünkü nesnelerin farklı uygulanımları için farklı nesne teknolojileri kullanılmasını sağlayan maksimum özgürlük amaçlamaktadır.

Nesne sistemlerinin NYG nesne modelinin kapsamı dışında başka özellikleri de mevcuttur. Bu kavramların bazıları uygulama mimarisi bakış açıları olup, bazıları nesne teknolojisinin uygulandığı belirli alanlarla ilişkilendirilmiştir. Bu tür kavramlar mimari referans modelinde daha düzgün bir şekilde ele alınmaktadır. Hariç tutulan kavramlardan bazıları, bileşik nesneler, öz nitelikler ve bağlantılar, nesnelerin kopyalanması, değişim yönetimi ve işlemlerdir (transactions). Ayrıca NYG nesne modeli kapsamı dışında denetim ve yürütme modeli de vardır.

Nesne modeli tanımında, yeni terimleri tanıtmak veya tanımlamak için italik kullanılır. Parantezli cümleler ve girintili paragraflar yorumdur ve nesne modelinin bir parçası değildir.

1.1 Klasik vs. Genelleştirilmiş Nesne Modelleri

Aşağıda tanımlandığı gibi, NYG nesne modeli genelleştirilmiş bir nesne modelidir. Bu nedenle, mevcut sistemlerden aşina olunan nesne modellerinden derin bir biçimde farklıdır. NYG nesne modeli kasıtlı bir şekilde, aşina olunan nesne modellerinin genelleştirilmesidir. NYG nesne modelini açıklamaya geçmeden önce, bu iki farklı nesne modelini karşılaştırmak ve farklarını vurgulamak faydalı olacaktır. Bu açıklamalarda kullanılacak terimler daha sonra açıklanacak olmasına rağmen, anlamlarının sezilmesi kolay terimlerdir.

Çoğu nesne teknolojisinde kullanılan klasik nesne modelinde, bir istemci nesneye mesaj göndermektedir. Kavramsal olarak, nesne, hangi hizmetin gerçekleştirileceğine karar vermek için mesajı yorumlar. Klasik modelde, talep, nesneyi ve sıfır veya daha fazla öz niteliği tanımlamaktadır. Çoğu klasik nesne modelinde, gerçekleştirilecek işlemi tanımlayan özellikle bir ilk parametre tanımlanması gerekir; Mesaj, talep edilen işlemi temel alan metodun seçilerek yorumlanır. Tabii olarak, metod seçimi nesne veya sistem tarafından gerçekleştiriliyor olabilir.

Genelleştirilmiş nesne modeli istemcinin bir işlem belirttiği bir talep ve herhangi birinin nesne belirtebileceği sıfır veya daha fazla öz nitelik bildiriminde bulunduğu modeldir. (Örnek olarak Genelleştirilmiş nesne modeli Common Lisp Nesne Sistemi ve Iris Veritabanı tarafından kullanılmaktadır.) Genelleştirilmiş nesne modelinde, metod seçimi, talebin yanı sıra işlemde tanımlanan nesnelerden herhangi birine dayanabilir. Yöntem seçimi birden fazla nesneye dayandığından, seçimin nesne değil sistem tarafından yapıldığı iyice görülmektedir. Metod seçimi, uygulamada çok aşamalı olarak gerçekleştirir, son aşama nesne tarafından tamamlanır.

Klasik nesne modeli, genelleştirilmiş nesne modelinin özel bir halidir. Nesneye klasik olarak bir mesaj göndermek, metod seçiminin işleme bağlı olduğu ve nesnenin ilk öz nitelik aracılığıyla tanımlandığı genelleştirilmiş talebe eşdeğerdir. Örneğin klasik modelde “yazdır yazıcı-a” mesajını “hesap_tablosu-a” nesnesine gönderme işlemi, metod seçiminin yazıcı-a nesnesine değil, hesap_tablosu-a nesnesine bağlı olduğu varsayıldığında, genelleştirilmiş modelde “yazdır hesap_tablosu-a yazıcı_a” talebini bildirmeye eşdeğerdir.

Genelleştirilmiş nesne modeli, bir nesne teknolojisinin ek işlevsellik sağlamasına olanak tanır. Örneğin, nesne teknolojisi, sadece bir elektronik tabloda ve belirli bir tür yazıcıda yazdırma işlemi talep edildiğinde çağrılan bir metodun tanımlanmasını destekleyebilir. Bu özelleşmiş metod, belirli yazıcı türlerinin benzersiz özelliklerinden yararlanabilir.

Klasik nesne modellerinin dağıtık uygulamaları genellikle nesnelerin konumlarını belirler. Genelleştirilmiş modellerde ise, işlemlere konumlar atamak da mümkündür. Böylece, uzaktan yordam çağrıları da genelleştirilmiş nesne modelinin özel bir örneğidir.

Genel bakış

NYG sistemi, kod ve veri içeren bir hesaplama sistemidir.

Bu belgede ele alınan bakış açısı, sadece tek bir NYG hesaplama sisteminin varolduğunu kabul etmektedir. (Sistem birden çok birbirinden ayrı hesaplama parçalarını içeriyor olabilir.) Bu bakış açısının sebebi, farklı hesaplama parçalarının, daha sonra tek bir parça olarak bağlandığı durumları zarifçe ele almaktır. Bu açıklama, belirli bir nesne teknolojisinde, bağımsız nesne sistemlerinin (ağlar), istendiğinde birbirine bağlanabilmesini desteklemesi gerektiğini belirtmemektedir. Diğer bir değişle, nesne modeli evrensel isimlendirme mimarisini desteklemek zorunda değildir.

NYG sistemindeki varlıklar, NYG nesnelerini, değerler (nesne adları ve tutamaçları dahil), işlemler, imzalar ve türleri (arayüz türleri dahil) içerir.

Nesne Semantiği

Bu bölüm, nesne semantiği ile ilişkili kavramları, yani nesneleri kullanma ile ilgili kavramları tanımlamaktadır. (Bkz. Şekil 1.)

3.1 Nesneler

NYG hesaplama modeli, NYG nesneleri olarak bilinen varlıkları içerir. (NYG nesneleri, C++ nesneleri gibi nesneler olarak da adlandırılan diğer muhtemel nesnelerle karıştırılmamalıdır. Kısaltma amacıyla, NYG nesnelerine bundan böyle nesneler denilecektir. Nesnelerin aşağıda açıklanan bazı özellikleri mevcuttur.
Bir nesne, istemcilere hizmet sağlama işleminde rol alır. Bir hizmetin istemcisi, hizmeti talep etme yeteneğine sahip herhangi bir varlıktır. (İstemciler, uygulama programları, nesneler, aracılar ve bir kullanıcı arayüzü aracılığıyla hareket eden son kullanıcıları içerebilir.)

3.2 Talepler

İstemciler talep bildirerek, hizmet talep ederler. Bir talep, diğer bir deyişle, hesaplama sisteminin çalışması esnasında, belirli bir zamanda meydana gelen bir şeydir. Bir taleple ilgili olan bilgi, istenen işlemden ve sıfır veya daha fazla (gerçek) öz nitelikten oluşmaktadır.

Bir talebin, çalıştırıldığında bir talep bildirilmesine yol açan, statik bir program metninden farklı birşey olduğu anlaşılmalıdır. Nesne modeli, hangi programların talep bildireceğini belirleyen bi söz dizimi dikte etmez. Örneğin talep bildiren bir yapıda, işlemin önce gelmesini gerektirmez. Nesne modeli, bir programın hangi işlemleri veya hangi öz niteliklerin çalıştırılma esnasında neye tekabül ettiği ile ilgilenmez.

Talep içerisinde belirlenmiş olan bir işleme, işlem adı denmektedir. Nesne modeli, istemcilerin işlemlere nasıl isim verdiğini de tanımlamaz. Farklı istemcilerin aynı işlemi tanımlamak için farklı isimler veya aynı ismi farklı işlemleri tanımlamak için kullanmaları mümkündür.

Birincil nesne semantiği kavramları

Talep dendiğinde anlaşılması istenen şey, işemin gerçekleştirilen hizmeti tanımladığı ve öz niteliklerin hizmet sunumuna katılan nesneleri ve istemci tarafından istenen sonuçları belirten diğer bilgileri tanımladığıdır. Bu nesne modeli, alışılagelmiş tek nesneli taleplere ek olarak, bir talebin sıfır veya daha fazla nesneyi adlandırmasına olanak vermektedir.

İşlemler (olasılıkla) jeneriklerdir, yani, nesnelerden talep edilen tek bir işlem, gözlemlenebilen farklı davranışlara yol açan, farklı uygulanımlara sahip olabilir.

Bu, hesaplama modelini karakterize etmesi amaçlanan felsefi bir ilkedir. Burada amaçlanan, farklı nesnelerden, belirli bir işlem talep edildiğinde, hizmeti gerçekleştirmeyi amaçlandığında yürütülecek kodun farklı farklı olabileceği ve farklı bir şekilde gözlemlenebilir davranışlara yol açabileceğidir. Özellikle, varolan işlemler için özelleşmiş davranışlar sağlayan yeni bir çeşit nesne sisteme eklenebilir. Belirli bir işlem için, farklı davranışlar, birşeyin yazdırılması gibi ortak bir amaca sahip olmaları beklenir, fakat, bu beklenti sistem tarafından zorlanan bir durum değildir.

İşlemler açık eylemler tarafından yaratılırlar, bu tarz eylemlerin her biri gelecekte yaratılacak veya daha önce yaratılmış olan işlemlerden farklıdır.

Bu tanımlama, aşağıda açıklanan nesne kimliğine eşdeğer bir kavram olan işlem kimliği fikrini açıklamaktadır. Temel bir seviyede, işlemlerde “kaza sonucu” aşırı yüklenme olamaz: İki istemcinin aynı işlemi belirtmesi için işlem kimliğinin ortak bir kaynaktan her bir istemciye iletilmiş olması gerekir. Dolayısıyla, geliştirici, (yeni bir işlem oluşturarak) hizmetin diğer hizmetlerden açıkça farklı olduğundan emin olacağı yeni bir hizmet tanımlayabilir.

Nesne mode bir işlemin bir nesne veya bir işlem adının (örneğin öz nitelik olarak kullanılabilecek) bir değer olduğunu tanımlamaz.

Talep kavramları

Değer, bir talep içerisinde bulunan, olası (gerçek) bir öz niteliktir. Değer, talebi gerçekleştirmek amacıyla, nesneyi tanımlayabilir. Nesneyi tanımlayan değere, nesne adı denir. (Bkz. Şekil 2.)

Nesneler dışındaki soyut varlıkları tanımlayan değerler olabilir. Bu tür değerlere değişmez (literal) denir. Örneğin, değişmez dendiğinde, bu değerlerin mutlaka derleme zamanı sabitleri olduğu kastedilmemektedir. Örneğin belirli bir sistemde, tamsayılar talepler içerisinde tanımlanmış olabilirler, fakat, sistem tarafından tanımlanan nesnelerin tüm özelliklerine sahip olmayabilirler. Başka bir deyişle, nesne modeli izin verse dahi tüm referanslanabilir varlıkların nesne olmasını gerekmez. Ayrıca, var olan herhangi bir varlığı referans göstermeyen anlamsız değerler de olabilir. Örneğin, henüz oluşturulmamış nesneleri tanımlamak için bazı değerler saklı tutulabilir. Bu durum, bir sonraki bahiste görmezden gelinmektedir.

Tanıtıcı (tutamaç, handle), belirli bir nesneyi açıkça tanımlayan bir nesne adıdır. Uzay, zamanın belirli pragmatik sınırları içerisinde, bir tanıtıcı, bir talep içerisinde kullanıldığı zaman, her seferinde aynı nesneyi güvenilir bir şekilde tanımlar.

Bir nesne teknolojisi, farklı nesneleri farklı zamanlarda veya farklı “lokasyonlarda” tanımlayan nesne adları sağlayabilir, örneğin belirli bir türdeki en yakın yazıcıyı gösteren bir değer gibi. Bu değerler nesne adlarıdır, ancak tanıtıcılar (handle) değillerdir. İkisi de yararlı olmasına rağmen, güvenilir, belirsiz olmayan nesne adlarının (tanıtıcılar) varlığı bir nesne sisteminin vazgeçilmez bir özelliğidir.

Nesne isimleri ve tanıtıcılar arasındaki ayrım, Unix dosya sistemine benzetme yapılarak anlatılabilir. Unix dosyalarının nesneler olduğunu ve bir Unix dosyasını tanımlamanın üç olası yolu olduğunu göz önünde bulundurun: yol adları, dosya tanımlayıcıları ve inode’lar. Bir yol adı, bir nesne adıdır, ancak bir tanıtıcı değildir, çünkü bir yol adına göre adlandırılmış dosya, dosyaları veya dizinleri yeniden adlandırma sonucunda anında değişebilir. (Göreceli bir yol adı, verilen bir işlem tarafından belirli bir zamanda “geçerli” olarak tanımlanan dosya dizinindeki yoruma bağımlı olmasıyla ek bir belirsizliğe sahiptir.) Bir dosya tanımlayıcı, bir tanıtıcıdır çünkü tek bir işlemde (veya dosya tanımlayıcıları paylaşılıyorsa işlem ağacında), aynı dosya nesnesini her zaman tanımlamaktadır. Bir inode belirli bir dosyayı tek bir dosya sistemi bağlamında belirgin olarak tanımlamış olsa da bir inode bir nesne adı değildir çünkü bir değer değildir (olağan Unix sistem çağrılarında kullanılamaz), Hem yol adları, hem de dosya tanımlayıcıları olması faydalıdır. Unix’in en büyük kısıtlılığı, dosya tanımlayıcısının kalıcı bir biçiminin olmamasıdır.

Nesne modeli, bir nesnenin tek bir bağlamda veya farklı bağlamlarda birden çok işleme sahip olmasını sağlar. Örneğin, bir Unix işlemi bağlamında bir tanıtıcı, o işlemin adres alanına işaretçi olabilir. Farklı işlemlerde, aynı nesne farklı işaretçilerle tanımlanır. Bu tür tanıtıcılar (handle), yalnızca işlemin adres alanı içinde ve yalnızca işlemin ömrü boyunca geçerlidir. (Yukarıdaki Unix dosya sistemi örneği, bir nesnenin tek bir bağlamda birden fazla tanıtıcısına işaret etmektedir: Bir Unix işlemi, aynı dosyayı tanımlayan birden çok dosya tanımlayıcısına sahip olabilir. Dosya tanımlayıcıları, dosyayla farklı ilişkili konumlara sahip olmalarıyla ayrışırlar.)

Bir nesne, bir veya daha fazla gerçek parametre o nesneyi tanımlıyorsa, bir talebe katılmak üzere tanımlanmıştır. (“Katılmak” sözcüğünü ile nesnenin gerçekten istenen hizmeti sunmasındaki herhangi görev derecesi kastedilmemektedir.)

Bir talep, bir hizmetin istemci adına gerçekleştirilmesine yol açar. Hizmeti gerçekleştirmenin bir sonucu, bazı sonuçların istemciye geri gönderilmesi olabilir. Bir taleple ilişkili sonuçlar, istenen hizmeti gerçekleştirmeye çalışırken istisnai koşulların ortaya çıktığını gösteren değerlerin birlikte farklı değerler de içerebilir.

Nesne modeli, bir istemci tarafından parametrelerin, sonuçların ve istisnai koşulların nasıl tanımlandığını belirtmez. Parametrelerin ve sonuçların tanımlanması ardışık / konumsal veya isimlerle olabilir. Bu ayrıntılar, bu modeli ayrıntılı olarak anlatan belirli bir nesne teknolojisi tarafından belirlenir.

Nesne modelinin, bir işlemin, istemci programlarında statik olarak tanımlanması gerektiğini belirtmediğini unutmayın. Örneğin, bir programlama dili arayüzü, işlem adının değişken olarak varolduğu bir talepte bulunmak için bir yapı sunuyor olabilir. Böyle bir yapı Lisp’deki “funcall” yapısına benzer olacaktır.

3.3 Davranış ve Soyutlama

Bir talebin davranışı, istenen hizmetin gerçekleştirilmesinden kaynaklanan gözlenebilir etkilerdir. (Etki, istekte bulunan istemci dışındaki taraflar tarafından görülebilir.) Bir talebin davranışı, istemciye (geri gönderilen değerler ve rapor edilen istisnai koşullar dahil olarak) geri döndürülen sonuçların yanısıra (aynı veya farklı bir istemci tarafından) gelecekteki sonuçlarla ilgili dolaylı etkileri içerir.

Genel olarak, bir isteğin muhtemel davranışları, diğer istekleri bildiren hesaplamaları da kapsayan herhangi bir rastgele hesaplamadır. (Bu ifade, hesaplama modelinin kastedilen gücünü karakterize etmektedir.)

Bir isteğin davranışı genellikle hem talebin gerçek öz niteliklerine, hem de hesaplama sisteminin durumuna bağlıdır. Hesaplama sisteminin durumu geçmiş isteklerin tarihçesinin bir gösterimidir; özellikle, geçmiş isteklerin gelecekteki davranış üzerindeki etkilerini temsil etmektedir. Bir davranış, öz nitelikleri, talebin gerçek argümanlarını ve sistemin durumunu içeren bir fonksiyon olarak modellenebilir. (Teknik olarak, bu teknik düzanlamsal semantik olarak adlandırılır.)

Sistemin durumu, fiziksel olarak, isteklerin yürütülmesi arasında kalıcı olan verilerle temsil edilir. Bu “kalıcı veriler”, nesne etkili bir şekilde temsil eden referansları içerebilir. Nesne modeli, bu gibi referansların depolanmış biçimi hakkında hiçbir şey söylemez. Kalıcı nesne referansları, yalnızca talep argümanları veya sonuçları olarak iletilmiş değerler (nesne adları) aracılığıyla istemciler tarafından görülebilir. Örneğin, kalıcı bir nesne referansı, bir nesnenin belirli bir öz niteliğini döndüren, hizmetin sonucu olan değer olarak, istemciye açıklanabilir.
Bir isteğin davranışı, bağlamsal bilgiye (örneğin, istemcinin kimliğine) ve sistemle bağlantılı olan (bağlı bir donanım aygıtının durumu gibi) diğer varlıkların durumuna veya kullanıcıların doğrudan etkileşimlerin etkilerine bağlı olabilir. Bu ilave etkiler, davranış fonksiyonuna ek argümanlar olarak modellenmektedir.

Bir nesne açıkça, ilgili taleplerin davranışı ile karakterize edilen soyutlamanın vücut bulmuş halidir. Bir nesne tarafından vücut bulmuş olan soyutlama, istemcileri için anlamlıdır. Son kullanıcı tarafından görülebilen bir nesne, tipik olarak, son kullanıcı tarafından aşina olunan bazı gerçek dünya nesnelerini modellemektedir.

Bu felsefi ilkeler, anlamlı soyutlamalar oluşturmak için nesneleri kullanmadaki amacı açıklamaktadır. Elektronik tabloları değiştirebilmeyi hedefleyen bir istemciye, elektronik tablolardan beklenen hizmetleri gerçekleştiren nesneler sunulmalıdır. Bir e-tablo nesnesinin e-tablo gibi davranması, nesnenin özünde bulunur ve istemcinin bilgisine bağımlı değildir. Unix’ten karşıt bir örnek konuyu açıklığa kavuşturmaya yardımcı olabilir. Unix dosyası, değiştirilebilir bir bayt dizisinin düşük seviyeli soyutlamasıdır. Bir Unix dosyasına ek semantik eklenmemiştir; bunun yerine, bir Unix dosyasının yorumu dosyayı işleyen uygulamalara bırakılmıştır. Bir Unix dosyası bir e-tabloyu temsil edebilir, ancak Unix dosya sistemi bu amacı belirlemez. Bunun yerine, bu özel Unix dosyası üzerinde çalışırken elektronik tablo uygulamasını çağırmak istemcinin sorumluluğundadır. Bu ifadelerle, birden fazla soyutlama seviyesini destekleyen sistemleri dışarıda bırakmak kastedilemiştir.

3.4 Nesnelerin Yaratılması ve Kimliği

Bir nesne, açık bir eylemle oluşturulur. Nesnenin kimliği vardır: daha önce yaratılmış olan veya hesaplama sisteminde yaratılacak olan her nesneden ayrıdır.

Nesne kimliğinin bu kavramı, her nesne yaratma olayında bir nesne tanımlayıcısının önceden ayrılmadığı sonsuz bir nesne tanımlayıcıları kümesi varsayılarak resmi olarak modellenebilir. Nesne kimliği, nesne tanımlayıcılarının denkliği olarak modellenir. (Soyut nesne kimliği konusundan aşağıda bahsedilmektedir.) Nesne modelinin, hesaplama sisteminde benzersiz nesne tanımlayıcılarını açıkça kullanmasını gerektirmediğine dikkat edin. Benzersiz tanımlayıcılar bir uygulama tekniğidir. Benzersiz tanımlayıcılar kullanılsa bile, istemcilere gösterilmelerine gerek yoktur.

Nesne oluşturma, işlemler yoluyla istemcilere sunulmaktadır. Nesne oluşturma işleminin sonucu, yeni oluşturulan nesneyi tanımlayan bir tanıtıcı şeklinde istemciye ifşa edilir.

Bir talebin davranışı, katılımcı nesnelerin kimliklerine bağlı olabilir. Özellikle, hesaplama sisteminin durumuna ait bir bileşen, belirli bir nesneyle benzersiz şekilde ilişkilendirilebilir. Genel olarak, böyle bir bu durum nesnenin katıldığı belirli talepler bildirilmeden değiştirilemez. Başka bir deyişle, farklı nesneler işlemler tarafından kapsüllenmiş ayrı bir duruma sahip olabilirler.

Bu ifadeler, hesaplama sisteminin kastedilen gücünü tanımlamaktadır. Belirtilen özelliklerle nesneleri tanımlamak mümkün olmalıdır. Kapsüllenmiş durumun klasik örneği, push (ekle) ve pop (kopar) hizmetlerini sunan yığın nesnesidir: örtülü olarak bir yığın nesnesi ile ilişkilendirilen durum, push (eklenen) edilen ama henüz pop edilmemiş (koparılmamış) öğelerin sırasıdır. Bu durum yalnızca push ve pop işlemleri ile değiştirilir. İstemcilere sadece pop’un zamanla değişen davranışıyla gösterilir.

Hesaplama sisteminin durumunun tek tek nesnelerle benzersiz şekilde ilişkilendirilmemiş ek bileşenleri olabilir. Örneğin, iki nesne kümesi, program kaynağı ve geliştirici nesneleri üzerinde yaratılmış ve tarafından-yaratılmış ilişkilerini düşünün. Bu işlemlerle sunulan durumun, nesne çiftleriyle veya işlemlerin alternatif olarak kendileriyle ilişkilendirildiği düşünülebilir. İlişkilendirilmiş durum denildiğine, durumun kalıcı gösteriminin şeklini sınırlandırmak kastedilmemektedir.

Nesne modeli, nesne yaratımı ve nesne yokedilmesi konusunda başka detaylar tanımlamamaktadır.

3.5 Soyut Nesne Kimliği

Nesneler, isteklerin davranışını etkiledikleri ölçüde istemciler tarafından ayırt edilebilme yeteneğine sahiptirler.

Diğer bir deyişle, nesne modeli, yukarıda tanımlandığı gibi nesne kimliğinin istemcilere doğrudan ifşa edilmesine izin verir ancak bu durumu zorlamaz. Nesne kimliği ile ilgili istemciler için uygun olan aşağıda gösterilen şekilde diğer olası kavramlar da vardır. Nesne modeli tarafından desteklenmese dahi, sistemin soyutlama yeteneklerinin, nesne kimliği ile ilgili soyut kavramların sağlanarak kullanılması mümkün olabilir. Bu kavramlar, istemciler tarafından talep edilen belirli hizmetler şeklinde gerçekleştirilebilirler. Örneğin, soyut bir nesne kimliği kavramına göre iki nesnenin kimliğinin “aynı” olup olmadığını karşılaştıran bir bir hizmet sunulabilir. Kastedilen soyut nesne kimliği kavramını temel alarak, hizmet, ayrık bir biçimde yaratılmış iki nesnenin “aynı” olduğunu bildirebilir. Nesne modeli, bu tarz bir hizmeti tanımlamamaktadır. Böyle bir hizmetin uygulanımını yapmak, nesnelerin ayrık bir şekilde yaratılmalarına göre test edilebilmelerini gerektirir.

Nesne kimliği konusuna daha soyut bir fikir örneği vermek gerekirse, “Kimlik birleştirme” kavramından bahsedilebilir. Bu fikir aslında birbirinden ayrık olan iki nesnenin, istemcilerin görüş açısından birbirinden ayılamayan, tek bir nesne haline gelmelerine izin verir. Nesneler gerçek dünyanın evrimleşen bir şekilde anlaşılması anlamında, dünyayı modellemek için kullanıldığında, örneğin, “Joe’nun babası” ve “Bob’un kardeşi” varlıklarının aslında aynı kişi olduğunu belirten bir modelleme için kullanıldığında faydalı olmaktadır.

Nesne kimliği fikri için daha soyur bir örnek (değişmez) matematiksel soyutlamalardır. Elemanları 1 ve 2 tamsayılarından oluşan bir küme kavramını matematiksel soyutlamaya örnek olarak verebiliriz. Bu şekilde sadece tek bir küme vardır. Nesneleri matematiksel soyutlamaları temsil etmek için kullanan bir sistemde, aynı soyutlamayı temsil etmek için birbirinden farklı çoklu nesneler var olabilir. Fakat, istemciler, bu nesneleri “özdeş” olarak görmelidirler. Bir hizmet, istemciler için bu ilüzyonu sağlayabilecek şekilde tanımlanabilmelidir.

Soyut nesne kimliğini desteklemek için gereken motivasyon, nesne modelinde doğrudan daha karmaşık kimlik biçimleri sağlamak yerine, yeni kimlik kavramlarını tanımlamadaki esnekliği sağlamak ve nesne teknolojisinin uygulanımları çok zor olan nesne kimliği kavramlarını desteklemesini önlemektir. Daha karmaşık nesne kimliği biçimleri, belirli bir nesne modelinde önlenmiş değildir.

3.6 Anlamlı talepler

Tüm talepler anlamlı değildir: bir nesne, tüm hizmetleri desteklemek durumunda olmayabilir ve bir talebin mevcut öz niteliklerinde başka kısıtlamalar varolmuş olabilir.

Anlamlı talep fikri, tip tabanlı sistemlerde, tiplerin hatasızlığı fikrine karşılık gelmektedir. Smalltalk’daki mesaj anlaşılamadı hataları bu fikre karşılık gelmektedir.

Her işlemin, o işlem için anlamlı olan olası (mevcut) öz nitelik değerlerini kısıtlayan ilişkili imzası vardır. Mevcut öz nitelikleri talep içinde tanımlanmış işlem imzasını tatmin etmeyen bir talep, anlamsızdır. Anlamsız bir talep bildirimi yapmak, istemciye bir istinsa koşulu rapor edilmesine yol açabilir.

Tip tabanlı programlama dillerine aşina olan okuyucular için, bir imza, bir prosedür veya fonksiyon tipi gibidir. Bu özel durumda, bir imza, (birden fazla türe sahip argümanları kabul eden) jenerik bir fonksiyonun türü gibidir. Örneğin, artı işleminin imzası, mevcut argümanların gerçel sayı veya tamsayıların bileşkesi olduğu ve bir tamsayı sonucunun eğer iki parametre de tamsayı olduğu (ya da gerçel sonucun iki parametre de gerçek olduğu), iki adet öz nitelik olmasını şart koşuyor olabilir.

Nesne Modeli, dilin imzalar tanımlamak zorunda olup olmadığını tanımlamamaktadır. Bu tarz bir nesne modelinin detaylanmış hali, belirli imza biçimlerini tanımlayabilir.

Eğer işlem isimleri (işlem isimlerinin talepler içinde öz nitelik olabildiği durumlar) değerler ise, imzalar aşağıda tanımlandığı gibi tip olarak düşünülebilir. Bu manada, Figür 1, işlemlerin tiplere sahip olduklarını göstermektedir.

Bir işlem yaratıldığında, imzası da belirlenmiş olur.

Nesne modeli bir işlemin yaratıldıktan sonra imzasını değiştirip değiştiremeyeceğini tanımlamamaktadır.

Bir imza, ilgili talepler ile ilişkili olan olası sonuç değerlerini veya istisnai koşulları karakterize edebilir. Bu ek bilgi, anlamlı talep fikrini etkilememektedir, ancak programların statik analizlerini gerçekleştiren araçlar tarafından kullanılabilir.

Nesne modeli, sonuçların olası karakterizasyonlarını tanımlamaz. Tipik olarak, sonuçları kendi tipleri açısından imzalar karakterize etmektedir. İmzalar işlem davranışının biçimsel veya biçimsel olmayan tanımları veya işlemin eşzamanlı olup olmadığı gibi ek bilgiler içerebilirler.

Bir tip, olası sonuçları karakterize eden veya olası öz nitelikleri kısıtlamaya yarayan bir imzada kullanılabilecek değerler üzerinde tanımlanmış (boolean fonksiyonu biçiminde olan) bir beyan biçimidir.

Bu açıklama, tip fikrine ilişkin çok genel bir tanım belirtmektedir. Bu tanıma göre, tamsayı gibi bir tür, bir tamsayı değerine uygulandığında true döndüren ve başka herhangi bir değere uygulandığında false döndüren bir işlem olarak düşünülebilir. Bu tanım, tek sayılar türü gibi daha alışılmadık türler tanımlanmasına olanak verir. Bu tanımın, tek bir değerin birden fazla türde olmasını (birden fazla tür işlemlerini tatmin edebilmesini) sağladığına dikkat edin. Örneğin, 1 numaralı tamsayıyı ifade eden değer, hem bir tam sayı, hem de tek bir tamsayıdır.

Nesne modeli, bir sistemde hangi tür tiplerin var olabileceğini tanımlamamaktadır. Bu modelin ayrıntılı bir şekilde ele alınması, türler için belirli bir biçimselliği tanımlayacaktır. Biçimselliğin seçimi, tip olarak kullanılabilecek işlem (predicate) kümesini kısıtlayabilir.

Tip kavramının bu tanımı, aynı nesneyi (veya başka bir soyut varlığı) belirten farklı değerleri birbirinden ayırmayı sağlayan tiplere olanak verir. (fakat zorunlu kılmaz.) Eğer belirli bir nesne modeli, aynı nesneyi (veya başka bir soyut varlığı) tanımlayan değerleri birbirinden ayırmaya yarayan tipleri sağlamıyorsa, tipler, (değerler üzerinde varolan işlemlerden hariç olarak) nesneler üzerinde varolan işlemler (predicate) olarak görülebilirler.

Hali hazırda varolan nesne-yönelimli programlama dilleri, sınıf adı verilen, nesnelerin birbirinden farklı uygulanımlarını birbirinden ayırmaya yarayan tipler sunmaktadırlar. Arayüz tipinin daha genel bir kavramı, jenerik işlemleri sezmeyi sağlayan alttaki açıklamada bulunmaktadır.

Nesne model, tiplerin nesneler veya çağırılabilen işlemler olup olmadıklarına bir kısıtlama getirmemektedir. Bazı sistemlerde, tip-kontrolü derleme zamanında gerçekleştirilir ve tipler çalıştırma sırasında temsil edilmezler.

Bir tipin genişletilmesi (extension), belirli bir tipi tatmin eden değerlerin kümesidir. Bir tipin genişletilmesi, yeni nesneler yaratıldığı sürece, zamana bağlı olarak değişebilir ve varolan nesneler üzerinde yan etkilere sebep olabilir.

Eğer tipler, aynı nesneyi tanımlayan birden çok değerleri ayırt etmiyorlarsa, tip genişletilmesi, değerlerin kendilerinden hariç olarak, sunulan değerler tarafından tanımlanan nesnelerin içerilmesi olarak görülebilir.

Bir ilişki, tipler üzerinde tanımlanan uygunluk olarak adlandırılmaktadır. Eğer a tipine uyumlu olan herhangi bir değer, b tipine de uyumluysa, a tipi, b tipine uyumludur.

Uyumluluk ilişkisini tanımlayacak olan belirli bir nesne modeli, mantıksal düşünce ile uyumlu olmalıdır. Uyumluluk, kalıtımın geleneksel kullanımlarından biri olan, nesnelerin hiyerarşik bir şekilde sınıflandırılmalarına olanak verir. Tip uyumluluğuna aşağıda bir örnek verilmektedir.

Bir nesne tipi, tip genişlemesinin bir nesneler kümesi olduğu tip çeşididir. (Tam olarak nesneleri tanımlayan değerler kümesidir.) Diğer bir deyişle, bir nesne tipi, sadece nesneler (nesneleri tanımlayan değerler) tarafından tatmin edilebilir.

Bir nesne birden çok tipi tatmin edebilir. Örneğin, bir Lotus 2.2 tablo nesnesi, (azalan belirginlikle) şu tipleri tatmin sırayla tatmin etmektedir: Lotus 2.2 tablosu, Lotus tablosu, yazdırılabilir nesne. Bu örnekte, bütün tipler uyumluluklarına göre ilişkilidirler. Bazı sistemler, bir nesnenin uyumlulukla alakalı olmayan tipleri tatmin etmesine olanak sağlayabilir. Örneğin, belirli bir bireyi tanımlayan bir nesne, kişi tipini ve hissedar tipini birlikte tatmin edebilir. (Hissedar olmayan kişiler veya kişi olmayan, örneğin, şirket olan hissedarlar var olabilir.)

Bir arayüz, nesnenin olası kullanımlarının kümesininin tanımıdır. Özellikle, bir arayüz, bir nesnenin anlamlı bir şekilde katılabileceği olası talep kümesini tanımlar. Bir nesne, arayüz tarafından tanımlanan her bir talep için anlamlı olması ile arayüzü tatmin eder denir.

Klasik nesne sisteminde, bir arayüz işlemler kümesinden oluşur. Örneğin, “yazdırılabilir nesneler” arayüzü, tek bir yazdır işleminden oluşabilir. Bir nesne, bu işlemlerden birini tanımlayan herhangi bir talebin ilk parametresi olarak anlamlıysa, klasik bir nesne arayüzünü tatmin eder denir.Genelleştirilmiş nesne modelini destekleyen bir sistem, nesnenin anlamlı olarak ortaya çıkabildiği işemlerin belirli biçimsel parametrelerini tanımlayan daha karmaşık arayüzleri destekleyebilir. Örneğin “yazdırılabilir nesne” arayüzü, yazdır talebinin ilk parametresi olarak görünen ve “yazıcı nesnesi” arayüzü, yazdır talebinde ikinci öz nitelik olarak ortaya çıkan bu nesneler tarafından tatmin ediliyor olabilir.

Arayüzler bir anlamda, imzaların ikilileridir. Taleplerin anlamlılığını belirleyen “kısıtlamalar” kümesi içeren, bir sistem düşünülebilir. İmzalar, bu bilginin işlem-merkezli görüşüdür ve arayüzler, bu bilginin nesne-merkezli görüşüdür. Nesne modeli, bu bilginin nereden kaynaklandığını belirlemez. Bir nesne, yazdır işleminin davranışını tanımladığı için yazdırılabilir olabilir. Alternatif olarak, bir nesne, yazdır işleminin beyan edilen ilk argümanın tipi olan yazdırılabilir nesneyi tatmin ettiği varsayıldığı için yazdırılabilir olabilir.

Bir arayüz tipi, herhangi bir nesne (harfi harfine nesneyi tanımlayan bir değer) tarafından tatmin edilebilen bir tiptir.

Bir arayüz, belirli bir nesnenin ne yapabileceğini ve istemcinin nesneyi nasıl kullanma niyetinde olduğunu aynı anda tanımlayabilir. Örneğin, bir arayüz tipi, bir prosedür için biçimsel öz niteliği bildirmek, mevcut öz nitelik nesnesinin prosedür içerisinde nasıl kullanılacağını göstermek için kullanılabilir.

Arayüz tipleri üzerinde uyumluluk küçük bir arayüz tarafından nasıl kullanılacağı açıklanan bir objenin, aynı zamanda daha büyük bir arayüz tarafından tanımlandığı şekilde kullanılabilmesi anlamına gelir. Arayüz tipleri üzerinde uyumluluk en azından basit tip sistemleri için, küme içermesi ile ilişkilidir. Yazdır ve Kopyala işlemlerinden oluşan arayüz, sadece yazdır işlemini içeren arayüzle, yazdırılabilen ve kopyalanabilen (içermeden dolayı) bir nesne basitçe yazdırılabildiği için uyumludur.

Her bir nesnenin, nesne için anlamlı olan bütün talepleri açıklayan esas (azami, en genel) bir arayüzü vardır.

Bir nesnenin esas arayüzü, yeni işlemler tanımlanması gibi belirli sebeplerden dolayı genişleyebilir veya daralabilir. Nesne modeli, istemsinin bir nesnenin esas arayüzünü belirleyebildiği bir hizmetin varlığına izin verir ama bunu zorlamamaktadır.

4. Nesne Uygulanımı

Bu bölüm, nesne uygulanımı ile ilgili kavramları, örneğin, nesnelerin uygulanımı ile ilgili kavramları tanımlar. (Bkz. Şekil 3.)

4.1 Taleplerin Gerçekleştirilmesi

İstenen bir hizmeti gerçekleştirmenin pratik etkisi depolanan bazı verilere erişen bazı kodların çalıştırılmasına neden olmaktır. Saklanan veriler, hesaplama sisteminin durumunun bir bileşenini temsil eder. Talep edilen hizmeti gerçekleştiren kod, sistemin durumunu durumunu değiştirebilir. Bir hizmeti gerçekleştirmek için yürütülen koda bir metod (yöntem) adı verilir.

Bir NYG sistemi, istemciler ve hizmetler arasındaki arabulucu olarak görev yapan bir altyapı içermektedir. (Tabii ki, bir hizmet kendi isteklerini yayınlayarak da bir istemci olabilir.) Altyapının birincil işlevi, istenen bir hizmeti gerçekleştirmek için uygun kodu seçmek ve bu kodu uygun verilere erişmek için çalıştırmaktır.

Nesne uygulanımının ana kavramları

Talep edilen bir hizmeti gerçekleştirmek ve metod tarafından erişilecek veriyi seçmeye bağlama (binding) denir. Bağlama, (tipik olara bir metodun) seçiminin, mevcut talep bildirilmeden önce olursa statik, veya seçim talep bildiriminden sonra yapılıyorsa dinamik olarak adlandırılır.

Statik bağlama, bildirimlere bağlı olarak derleyiciler tarafından gerçekleştirilir. Talep bildiren bir program yapısı genellikle değişkenler içerir. Programdaki bildirimler, bu değişkenler tarafından ifade edilen olası değerleri kısıtlayabilirler.

Talep edilen bir hizmeti gerçekleştirilen kod belirli etkenlere, özellikle talebe katılan nesnelerin kimliğine bağlı olabilir.

Katılan nesnelere bağlı olan kod seçimi, bir işlemin jenerik olarak açıklanmasına temel oluşturur. Klasik bir nesne modelinde, seçilen kod, sadece bir talebin ilk öz niteliği tarafından tanımlanan nesne sınıfı ve işleme bağlıdır.

Seçilen kod ayrıca, nesnenin “konumu” veya istemcinin “konumu” gibi diğer etkenlere de bağlı olabilir. (Nesne modeli bir konum kavramını zorunlu kılmamaktadır.) Belirli bir nesne teknolojisi istemciler için artırılmış bir öngörülebilirlik sağlayan bağlama işlemi üzerinde kısıtlamalar empoze edebilir. NYG modeli, kasıtlı olarak bunun gibi kısıtlamalar empoze etmemektedir.

Talep edilen bir hizmetin gerçekleştirilmesi, kaydedilmiş bir veriye erişebilen bir metodun çalıştırır. Eğer metodun ve verinin kalıcı biçimi çalıştırılamıyorsa, önce çalıştırılamayan metodu ve veriyi, çalıştırılabilir bir adres alanına kopyalamak gerekli olabilir. Bu işleme aktivasyon denir. Bunun tersini yapan işleme ise pasifleştirme denir.

4.2 Davranışın gerçekleştirilmesi

Bir NYG sistemi, taleplerin davranışlarının gerçeğe dönüştürülmesini sağlayan mekanizmaları sunmak zorundadır. Bu mekanizmalar, veri yapısı tanımları, metod tanımlamaları ve NYG altyapısının çalışacak metodların ve metodlar için erişilebilir hale getirilen verilerin seçiminin nasıl yapılacağının tanımlamalarını içerebilir. Mekanizmalar ayrıca yeni verilerin tahsis edilmesi ve nesnenin uygun metodlarla ilişkilendirilmesi gibi, nesne yaratımı ile ilgili olan somut eylemleri tanımlamak için sağlanmak zorundadırlar.

Bir nesnenin uygulanımı -ya da kısaca uygulanım- nesnenin yaratılması ve nesnenin uygun hizmet kümesine katılımını sağlayan bilgilerin tanımlanmasıdır. Bir uygulanım, tipik olarak, bir nesneyle ilişkili olan çekirdek durumu temsil eden veri yapısının tanımını ve bunun yanısıra bu veri yapısına erişen metodların açıklamalarını içerir. Ayrıca, tipik olarak, nesnenin niyet edilen tipi hakkında bilgi içerir. (Bir uygulanım, varolan bir nesneye yeni davranışlar eklemek için de kullanılabilir.)

Bir NYG sistemi, metod tararından gerçekleştirilmekte olan hizmet için varolan talebin içinde tanımlanan nesne veya nesnelere referans veren metod tanımlarına izin veriyor olabilir. Kendine-referans olarak adlandırılan bu yetenek, bir metodun, aynı nesne ya da nesneleri dahil eden ek taleplerde bulunmasına olanak verir. Kendine-referans, tek bir metod, farklı nesneler tarafından çalıştırılabildiğinde yararlıdır. (Smalltalk’ta kendine-referans self kelimesi ile gösterilir.)

4.3. Davranışın paylaşılması

Bir NYG sistemi, tipik olarak, uygulanımı paylaşan aynı davranışa sahip olan nesnelere izin veren mekanizmaları sağlayacaktır. Bir sınıf, birden fazla nesnenin yaratılması için örneklenebilen (instantiated) uygulanımdır. Sonuç olarak ortaya çıkan nesnelere, sınıfın örnekleri denir. Kendine-referans, bir sınıfın birden çok örneği, metodları paylaştığında yararlıdır.

Ancak, aynı davranışı destekleyen birbirinden farklı uygulanımlar da olabilir. Örneğin, belirli bir donanım ortamı için belirli uygulanımlar mevcut olabilir. Ayrıca, zamanla, performans artırımı için sunulmuş olan uygulanım serileri de mevcut olabilir.

Çoğu varolan sistemde, sınıflar, uygulanımı ve arayüz tipini birlikte tanımlamaktadırlar. Bu görevleri tek bir varlıkta birleştirmek, bir sistemin aynı davranışın farklı uygulanımlarını desteklemesini zorlaştırabilir. Bir sınıf, bir nesne olabilir veya olmayabilir.

Bir NYG sistemi, tipik olarak kendi uygulanımlarının bazı kısımlarını ortak kullanan benzer davranışlara sahip nesnelere izin veren mekanizmalar sunacaktır. Örneğin, bir uygulanım kalıtımı, bir uygulanımın artımlı bir şekilde düzelmesi olarak tanımlanan uygulanıma izin vermek için sağlanıyor olabilir.

Uygulanımların ortak kullanımını sağlayan alternatif bir teknik delegasyondur. Delegasyon, talebi gerçekleştiren metodun içindeki kendine referansın, talebi bildiren metodda kendine referans olarak aynı nesne veya nesneleri döndürebilmesi yeteneğidir.

5. Sözlük

Aktivasyon: (activation) Metodların ve kaydedilmiş verinin kalıcı biçiminin, çalıştırılabilir bir adres alanına, metodların, kaydedilmiş veriler üzerinde çalışmalarını sağlamak için kopyalanması.
Davranış: (behavior) Bir talebin davranışı, talep edilen hizmetin (sonuçları içerecek şekilde) yarattığı gözle görülebilen etkileridir. (Bakınız sonuçlar.)
Bağlama: (binding.) Talep edilen hizmeti gerçekleştirmek için varolan kodun ve kod tarafından erişilecek verinin seçilmesi. (Bakınız metod)
Sınıf: (class) Bir sınıf, aynı (başlangıç) davranışa sahip olan nesnelerin yaratılması için örneklenebilen uygulanımdır.
İstemci: (client) Bir istemci hizmet talep edebilen herhangi bir hesaplama varlığıdır.
Uygunluk: (conformance) Uygunluk, mantıksal düşünüşle uyumlu olan tipler üzerinde tanımlanmış olan ilişkidir. A tipini tatmin edenherhangi bir değer, aynı zamanda b tipini de tatmin ediyorsa, bir a tipi, b tipine uygundur denir.
Dinamik Bağlama: (dynamic binding) Talep bildirildikten sonra gerçekleştirilen bağlama işlemidir.
Delegasyon: (delegation) Delegasyon, talebi gerçekleştiren metodun içindeki kendine referansın, talebi bildiren metodda kendine referans olarak aynı nesne veya nesneleri döndürebilmesi yeteneğidir. (Bakınız kendine-referans)
Kapsüllenmiş: (encapsulated) Bir nesne, ilişkili olduğu durum sadece belirli metodlar tarafından erişilip değiştirilebiliyorsa, kapsüllenmiştir.
Tipin genişlemesi: (extension of a type) Bir tipin genişlemesi, tipi tatmin eden değerler kümesidir.
Jenerik işlem: (generic operation) Kavramsal düşünce. Bir işlem, gözle görülür farklı davranışlara yol açan, farklı uygulanımlara sahip nesnelerden talep edilen bi hizmeti tanımlıyorsa jeneriktir denir.
Tutamaç: (handle) Tutamaç, nesneyi güvenilir bir şekilde tanımlayan bir değerdir. (Bakınız nesne adı)
Kimlik: (identity) Kavramsal düşünce. Bir varlık doğası gereği diğer varlıklardan ayır edilebiliyorsa, (örneğin ayrık yaratım olayları temelinde) bir kimliğe sahiptir denir.
Uygulanım: (implementation) Bir uygulanım, bir nesnenin yaratımı ve nesnenin uygun olan hizmet kümesini sunmadaki katılımı için gerekli olan bilgiyi sağlayan açıklamadır. Bir uygulanım, tipik olarak, bir nesneyle ilişkili olan çekirdek durumu temsil eden veri yapısının tanımını ve bunun yanısıra bu veri yapısına erişen metodların açıklamalarını içerir. Ayrıca, tipik olarak, nesnenin niyet edilen tipi hakkında bilgi içerir.
Uygulanım kalıtımı: (implementation inheritance) Diğer uygulanımların artımlı bir şekilde düzeltilmesiyle meydana gelen uygulanım yapısı.
Kalıtım: (inheritance) Diğer tanımlamaların artımlı bir şekilde düzeltilmesiyle meydana gelen tanımlama yapısı. (Bakınız uygulanım kalıtımı)
Örnek: (instance) Bir sınıfın örneklenmesiyle yaratılan nesne.
Örnekleme: (instantiation) Bir sınıf kullanarak bir nesne yaratma işlemi.
Arayüz: (interface) Bir arayüz, nesnenin olası kullanımlarının kümesini tanımlamasıdır. Özellikle, bir arayüz, bir nesnenin, anlamlı olarak katılım sağlayabildiği olası talepleri tanımlar.
Arayüz tatmini: (interface satifaction) Bir nesne, arayüz tarafından tanımlanmış her bir olası talep için anlamlı ise bir arayüzü tatmin eder.
Arayüz tipi: (interface type) Bir arayüz tipi, belirli bir arayüzü tatmin eden her nesne tarafından tatmin edilen tiptir. (Bakınız nesne tipi)
Sabit: (literal) Nesne olmayan bir varlığı tanımlayan değer. (Bakınız nesne adı)
Anlamlı: (meaningful) Bir talep, mevcut öznitelikleri, söylenen işlemin imzasını tatmin ediyorsa, anlamlıdır.
Metod: (method) Talep edilen bir hizmeti gerçekleştirmek için çalıştırılabilen kod.
Nesne: (object) Bir NYG nesnesi, NYG hesaplama sisteminde, ayrılmış bir varlık tipidir.
Nesne Yaratımı: (object creation) Bir nesnenin daha önce varolan nesnelerden farklı olacak şekilde varolmasını sağlayan olay.
Nesne Uygulanımı: (object implementation) Bakınız uygulanım.
Nesne Adı: (object name) Bir nesneyi tanımlayan değer. (Bakınız tutamaç)
Nesne Tipi: (object type) Bir nesne tipi, genişlemesinin bir nesneler kümesi (harfi harfine nesne tanımlayan değerler kümesi) olduğu bir tiptir. Diğer bir deyişle, bir nesne tipi, sadece nesneler (nesneyi tanımlayan değerler) tarafından tatmin edilir. (Bakınız arayüz tipi)
İşlem: (operation) Bir işlem, talep edilebilen tanımlanmış bir hizmettir. Bir işlemin ilişkili olduğu, anlamlı bir talep içerisindeki öz nitelikleri kısıtlayabilen bir imzası vardır.
İşlem adı: (operation name) Bir işlemi tanımlamak için bir talep içerisinde kullanılan isim.
Katılmak: (participate) Bir nesne, talebin bir veya birden fazla özniteliği, o nesneyi tanımlıyorsa, talebe katılır.
Pasifleştirme: (passivation) Aktivasyonun tersi.
Esas arayüz: (principal interface) Bir nesnenin esas arayüzü, nesnenin anlamlı olduğu bütün talepleri tanımlayan arayüzdür.
Talep: (request) Talep bir olaydır. Bir istemci, bir hizmetin gerçekleştirilmesi için talep bildiriminde bulunudur. Bir taleple ilişkili olan bilgi, sıfır veya daha fazla (mevcut) öz nitelikten oluşur. Ayrıca, istemciye dönebilecek olan sonuçlar da taleple ilişkilidir.
Sonuçlar: (results) Bir talebin sonuçları, istemciye geri dönen, talep edilen hizmetin gerçekleştirilmesi sırasında ortaya çıkan istisnai koşulları gösteren durum bilgisi gibi değerleri içerebilen bilgidir. 
Kendine-referans: (self-reference) Kendine referans, bir metod tarafından gerçekleştirilmekte olan hizmet talebinde tanımlanan nesne ya da nesnelerin, metod tarafından saptanması yeteneğine denir. (Smalltak’da kendine referans self kelimesiyle gösterilir.) (Bakınız delegasyon)
Hizmet: (service) Bir hizmet, talebe bağlı olarak gerçekleştirilebilen hesaplamadır.
İmza: (siganture) Bir imza, işlemi adlandıran taleplerde anlamlı olan, olası (mevcut) öz nitelik değerlerinin kısıtlandığı işlem tanımıdır. Mevcut öz niteliklerinin talepte adlandırılmış işlem ile ilişkili olan imzayı tanımlamadığı talepe, anlamsız talep denir.
Durum: (state) Bir hesaplama sisteminin durumu, gelecek taleplerin davranışını açıklamak için ihtiyaç duyulan eski taleplerin tarihçesi hakkındaki bilgidir.
Statik Bağlama: (static binding) İstemcisinin statik özelliklerine bağlı olarak, talebin bildirilmesinden önce gerçekleştirilmiş bağlama işlemidir.
Tip: (type) Tip, olası bir sonucu karakterize eden veya, olası öz nitelikleri kısıtlayan imzada kullanılabilen değerler üzerinde tanımlanan işlemdir. (predicate) (boolean fonksiyonu)
Değer: (value) Bir değer, bir talepte olası mevcut değer olabilen herhangi bir varlıktır. Nesneleri tanımlamaya yarayan değerler, nesne adı olarak adlandırılır. Nesneler dışındaki varlıkları tanımlayan değerler, sabit olarak adlandırılır. (literals)

Referanslar

[1] D. H. Fishman, et al. Iris: An Object-Oriented Database Management System. ACM ‘Iransactions on Office Information Systems, 5:1 (Jan. 1987). 
[2] S. Keene. Object-oriented programming in Common Lisp. Symbolics Press and AddisonWesley, 1989. 
[3] A. Snyder. The Essence of Objects. Report STL-89–25, Hewlett-Packard Laboratories, Palo Alto, California, 1989.


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Hiç Bilmeyenler İçin Nesne Yönelimli Programlamaya Giriş

Uyarı: Bu serideki kod örnekleri ve yazılar, seri tamamlanana kadar değişebilmektedir.

Nesne Yönelimli Programlama’yı duydunuz. Kendinizi geliştirmek için öğrenmek zorunda olduğunuzu öğrendiniz. Ancak nereden başlamak gerektiğini bilmiyorsunuz. Bi kaç kitap açtınız, kafanız karıştı, kitabı yatağın üzerine fırlattınız ve spagetti kod yazmaya, müşterinize böyle uygulamalar sunmaya devam ettiniz. İçten içe bir suçluluk duyuyorsunuz ama yapacak birşey yok deyip hayatınıza devam ettiniz. Artık buna bir dur demenin zamanı geldi.


Bildiğiniz gibi ben kuru kuruya kavramları anlatmayı sevmiyorum. İnternetten bulduğu slayttan ders anlatan hocalar gibi ezberden kavram sıralamayı doğru bulmuyorum. Piyasada çok güzel kaynaklar, detaylı kapsamlı kullanım klavuzları var ama ben kavramları anlatmak için Hayvan sınıfı, Memeliler sınıfı, At sınıfı ve Eşşek sınıfı gibi hayatınızda hiçbir yazacağınız programda olmayacak kavramları da kullanmayı sevmiyorum. Detaylı kaynakları konunun mantığını kavradıktan sonra satın alıp, gerçek, profesyonel uygulamalar geliştirirken açıp bakarsınız. Mesela Rıza Hoca’nın A-dan Z-ye PHP kitabı vardır. Tavsiye ederim. Ama konuyu hiç bilmiyorsanız, kendinizi bana bırakacak, önce minik adımlarla, masal dinler gibi beni dinleyeceksiniz.


Neden nesne yönelimli programlama öğreneyim ki?

  1. Çünkü bir sonraki aşamaya, yani düzenli, temiz, dünyadaki standartlara uygun, tekrar kullanılabilir, kodu açtığımızda profesyonel birine göstermeye utanmayacağımız kodlar yazmak istiyoruz.
  2. Bizden sonra spagetti karman çorman kodumuz üzerinde çalışacak gariban yazılımcının edeceği küfürler yüzünden kulaklarımızın çınlamasını istemiyoruz. Kodumuz okunabilir oluyor. Karmaşa azalıyor.
  3. Minik minik, kendi projelerimize ait kütüphane oluşturup, yeni projelerde bunları modüler olarak kullanabilmek istiyoruz. Tıpkı Lego gibi. Kodumuz yeniden kullanılabilir oluyor.
  4. Ben zamanında spagetti kod yazarken, kendi kodumu okuyamadığım oluyordu, sonra kendime küfrediyordum, bunun da olmasını istemiyoruz.
  5. Nesne yönelimli programlamanın temel kavramlarını öğrendiğimiz zaman, diğer nesne yönelimli programlama dillerini kolayca kavrayabiliyoruz ve o dilleri kolayca öğrenebiliyoruz.
  6. İyi okunabilen kodlarda, karmaşa daha az olduğu için, hataları yakalamak daha kolay oluyor.
  7. Test edilebilen kodlar yazabiliyoruz. Bu sayede daha sonra ortaya çıkabilecek hataları önceden yakalayabiliyoruz.

Nesne yönelimli programlama öğrenmek istiyorum. Peki nereden başlamalıyım?

Hiç kod yazmaya girmeden önce kavramları, yani konunun mantığını anlamamız gerekiyor. “Nedir bu nesne kavramı? Ne işe yaradığını az çok anlattık ama tam olarak nedir? Hocam, gerçek hayatta bu ne işime yarayacak?” diye lisede, zavallı öğretmenlerimize ergen kafasıyla ukala ukala sorduğumuz soruların cevabını önce kendimiz verebilecek hale gelmemiz gerekiyor. Yani nesne yönelimli programlayı öğrenmek ve anlamak biraz da bilinç meselesi. Bilinçli, yani ne yaptığımızın farkında olarak çalıştığımızda, üreteceğimiz eserlerin iyi veya kötü, kaliteli veya kalitesiz olup olmadığını kendimiz bilirsek, o zaman kendimize güvenimiz de, başkalarının da bize olan güveni de otomatik olarak artıyor.

Peki nedir bu Allahın belası Nesne kavramı?

Aristo abimiz. Yakışıklıymış da.

Kitabı yazmaya başlarken, nesne kavramını çok iyi anladığını sanan ben, konuyu araştırmaya başladığımda olayın yazdığımız salak programları “class” bloklarının içine sokmaktan daha derin olduğunu gördüm. Programlama konusunun temeline indiğimde orada matematikle karşılaştım. Matematiği anlamaya çalıştığımda, aslında çabalarımızın felsefeden başka bir şey olmadığını gördüm. Yani, uğraştığımız şey, dünyadaki olayları anlamak, bunun bir şekilde yorumlamak ve elle tutulur bir değişim yaratacak bir sonuca ulaşma çabası göstermekten ibaret. Yazacağımız programlar, yaptığımız işler görülebilir bir değişiklik yaratmak üzerine. Tam da bu noktada programlamadan çıkıp gerçek hayata geçiyoruz ve anlıyoruz ki nesne dediğimiz varlık sadece basit bir programlama kavramı değil.

Nasıl yani?

Yanisi şöyle. Nesne kavramının, dilbilimde (hani özne-nesne, tümleç, yüklem falan var ya.), fizikte (belirli bir yükseklikten, belirli hızda düşen, kütlesi olan nesne), psikolojide (algıladığımız nesneler) yeri var. Biz bilgisayarlarla ilgili olduğumuzdan, bilgisayarlar da düşünen elektronik beyinler olduğundan kavramın düşünce ile ilgili olan tanımına bakalım.

nesne İng. object

(Lat. objectum = karşıda bulunan, karşıya konan) : 1. (Genellikle) Karşımızda bulunan şey. 2. Öznenin bağlılaşık kavramı olarak, özne ediminin, bilincin kendisine yöneldiği şey: a. Kendisine yönelinen, düşünülen, tasarlanan nesne, kendisine yönelen bir edim olmadan var olmayan şey; bilinçte, düşünme nesnesi (konu) olarak düşünme olayının karşısında bulunan şey; düşüncel (ideal) nesne. b. Özne ediminden, bilinçten, bağımsız olan gerçek (real) nesne; gerçeklik olarak, dışdünyanın bir parçası olarak bilincin karşısında duran şey.

BSTS / Felsefe Terimleri Sözlüğü 1975

Şey diye bitirmiş. Peki şey nedir? Ona da bakalım.

şey İng. thing

(Günlük dilde) Herhangi bir düşünce konusunu göstermeğe yarayan belirsiz terim. (Felsefede) 1. Düşünen bilincin konusu olabilen, gerçekte var olmayıp da yalnızca düşünülmüş olan her şey. Bu anlamda: düşünce nesnesi = ens rationis. 2. Kişiye karşıt olarak: Bilinçten yoksun varlık. 3. Gerçek olan, bilincin dışında, kendi başına var olan tek nesne (ens reale). Böyle bir var olan, tek nesne olarak niteliklerin taşıyıcısı töz diye de anlaşılır. 4. Duyularla kavranabilen cisimsel nesne.

BSTS / Felsefe Terimleri Sözlüğü 1975

Bu tanımdan şunu anlıyoruz. Birşeyin nesne olabilmesi için belirli kurallar var.

  1. Düşünen aklımızın, yani zihnimizin dışında olacak.
  2. Düşüncemizin konusunu oluşturacak, yani düşüncemize yakıt oluşturacak.
  3. İsmi varsa nesne, ismi yoksa şey olarak adlandırılacak.

İnsanlar olarak bizim, evrim sürecinde, hayvanlardan farklılaşmamızın en büyük ayırt edici özelliği, düşünebilmemizdir. Düşüncenin dil kavramının insanlarda ortaya çıkmasıyla başladığını biliyoruz. Kaynak

Peki düşünce nedir? Nasıl başlar? Düşünce algı ile başlar. Kendi dışımızdaki ortamda algıladığımız sinyaller, önce beynimize gider. Bu kısaca 3 saattir aradığın, önünde duran ama görmediğin ve salak salak aradığın anahtara baktığın aşama oluyor. O şeyin anahtar olduğunu anladığın anda, algı sürecin tamamlanıyor.

Daha sonra bu algılar ile belirli sonuçlar üretmemiz gerekiyor ki düşünme eylemimiz amacına ulaşsın. Burada, bilgisayar programları veya algoritmaları ile varolan benzerlik dikkatinizi çekti mi? Bilgisayar programları ile biz belirli girdiler kullanarak belirli sonuçlara ulaşmaya çalışıyoruz. Girdi-İşleme-Sonuç adımlarıyla programları çalıştırıyoruz. Düşünce kavramında da, girdiler algılanmış nesnelere, işlem düşünceye ve sonuçlar yani çıktılar, çıkarımlara denk geliyor. Bizim bilgisayarlardan farkımız, benlik bilincine sahip olmamız ve etraftaki kendimizden farklı olan nesnelerin bizim dışımızda olduğunu idrak etmemizden kaynaklanıyor. (Bu konuyu, özellikle yapay sinir ağları konusunu daha derinlemesine araştırırsanız bundan bir 5 sene sonra zengin olacağınızı garanti ediyorum.) Yani nesne, düşüncemizin konusu olan soyut ya da somut varlıkları, önce kendimizden daha sonra birbirlerinden ayırt etmemizi sağlıyor. (Burada da mantık konularına giriyoruz. Üniversite ders kitabı falan yazarsam bu kavramlara derinlemesine ineceğim söz.)

Gerçek olan ne?

Bakışlara dikkat. Descartes

Yani ben gerçekten varolduğumu nasıl anlıyorum? Bu konuda Rene Descartes 1637 “Cogito ergo sum” demiş. Yani “Düşünüyorum, o halde varım.” Düşünme eyleminin kendi zihnimizden bağımsız bir dünyanın varlığını gerektirdiğini biliyoruz. fMRI denen beyin taraması insana birşey gösterildiğinde, beynin hangi bölgelerine kan akışı olduğunu gösteriyor. Yeni bilimsel gelişmeler sayesinde, önce zihinden bağımsız varlığın, sonra algı kavramının düşünme kavramının öncülü olduğunu da öğrenmiş bulunuyoruz. Descartes abimizin haklı olduğunu bu sayede anlıyoruz. Yani nesne kavramını oluşturabilmemiz için önce bir içsel zihne (ya da bilgisayar programlarında, çalışan bir hesaplama ünitesine) daha sonra da algılara ihtiyacımız var. (Bu da bilgisayar programlarında girdilere denk geliyor.)

İnsanlar olarak mantıklı düşünmenin önemini biliyoruz. Konuya mantık açısından baktığımızda mantığın en temel kavramlarıyla da ilişki içinde olduğumuzu görmek kolay. Kaynak

Mantığın 4 temel ilkesi diyor ki:

  1. A, A’dır. (Özdeşlik ilkesi)
  2. A, A olmayan değildir. (Çelişmezlik ilkesi)
  3. C, ya A’dır, ya da A olmayan’dır. (3. şıkkın imkansızlığı ilkesi)
  4. Sonuç varsa, sebep vardır. (Yeter sebep ilkesi)

Matematiğin bile temellerini oluşturan bu düşünsel ilkeler, nesne kavramı için de aynı şekilde geçerlidir. Nesneleri, kendimizden, düşünen zihnimizden ve diğer nesnelerden ayırt edebiliyorsak (1. ve 2. ilke), Nesnelere farklı isimler ile referanslar verebiliyorsak (3. ilke) ve düşünürken ya da programlar yazarken girdilerin, sonuçlar üretebileceğini biliyorsak (4. ilke), mantıklı düşünebiliyoruz demektir.

(Not: Kanıtı olmayan gerçekler kitabı’nda gerçekliğin fiziksel varlıklardan çok, bu varlıkların kendileri dışında yarattığı etkileri de içerdiği iddia ediliyordu. Yani, Mozart, eserleri ile birlikte yaşamaya, düşüncesindeki deseni farklı insanalara aktarmasıyla yaşamaya devam ediyor diye iddia ediliyordu. Bunu da yazayım da kafanız daha da karışsın.)

Nesne yönelimli programlama nerden çıktı?

Ole-Johan Dahl ve Kristen Nygaard abilerimiz

Norveç’te 1961 yılının soğuk bir sonbahar akşamı, yani soğuk derken -25 falan, Ole-Johan Dahl ve Kristen Nygaard abilerimiz, Simula denen programlama dilini icat ediyorlar. Kaynak Amaçları, yazılan programların insanlar tarafından daha kolay anlaşılmasını ve gerçek hayatta varolan bilimsel olayların daha verimli bir şekilde simüle edilmesini sağlamak.

Alan Kay

Nesne yönelimli programlamayı yaygınlaştıran Alan Kay abimiz, 1971 yılında Amerika’da Smalltalk programlama dilini icat ediyor. Alan Kay abinin bu konudaki motivasyonu ise, kendisi biyoloji kökenli olduğundan, programları, birbiriyle konuşan, birbirinden bağımsız hücreler gibi düşünmesi. Yani kendisinin sahip olduğu biyoloji temeli bugünkü kullandığımız programlama dillerine de temel oluşturuyor. Daha çok merak edenler için kaynak.


Burada Nesne Yönelimli programlamanın tarihçesine inmek istemiyorum. Araştırmanızı, okumanızı tavsiye ederim. Bu yazı ders kitabı haline gelirse bunu da yazarım.

Özne-nesne ilişkisi

Ali Topu At

Nesnelerin zihnimizin, ya da bilgisayarımızın dışında varlıklar olduğunu ve kavramları birbirinden ve kendimizden ayırt etmemize yardımcı olduğunu anladık. Bunun dışında nesnelerin gerçek dünyaya referans verdiğini, gerçek dünyadaki kavramları temsil ettiğini de az çok biliyoruz. Peki nesneler birbirileriyle nasıl ilişkilere sahipler. Bir nesneyi kullanan, onun üzerinde etkisi olan nesneye, özne diyoruz. Dilbilimde, “Ali topu at!” derken, Ali’nin özne, topun nesne, atmak kelimesinin de yüklem, yani yaptığımız işlem olduğunu biliyoruz. Bilgisayar programlarında, özne, bir diğer nesneyi çağıran, ona mesaj gönderen, onu yaratan bir bilgisayar programıdır.

Üyelik ilişkisi (IS-A)

Nesneler belli bir grubun üyesi olabilirler, yani daha üst bir sınıfın özelliklerine sahip olabilirler. Bu sayede birden fazla nesne grubunu, başka gruplardan ayırt edebiliriz. Eski yunanda yaşayan en büyük düşünür Aristo abimiz, taksonomi bilimiyle, canlı varlıkları, ortak özelliklerine göre sınıflandırmış. Biz de nesneleri aynen bu şekilde sınıflandırabiliyor, birden fazla nesneyi ortak özelliklerine göre gruplandırıp onları tek tek belirtmeden, düşüncemizin konusu haline getirebiliyoruz. Yani, Ali, Ayşe, Ahmet, Mehmet demek yerine, “Gıcık insanlar” diyebiliriz mesela. Ayrıca bir grubun üyesi olmayan iki ayrı nesne, aynı eylem içinde birlikte yer alıyorlarsa, onlar da belirli bir grubun içinde kabul edilebilirler. Örneğin, “Ali ve Ayşe İstabul’a gittiler” dediğimizde, Ali ve Ayşe’nin gitme eylemini yapabilen türden varlıklar olduklarını anlayabiliriz. Kaynak

Nesneler farklı nesnelerin bir araya gelmesiyle oluşabilirler. (HAS-A)


Yukarıda verdiğimiz grup örneğinde, eğer oluşturduğumuz grubun kendisi de bir nesne olarak kullanılabiliyorsa buna, Toplama (yani Aggregation) diyoruz. Örneğin, bir etli türlü yapmak için, patlıcan, domates, bamya, tereyağı kullanıyoruz ve sonuç olarak etli türlü elde ediyoruz. Elde ettiğimiz sonuç yine bir nesne meydana getirebilir. Kaynak

Nesnelerin kendilerine ait özellikleri ve yapabildikleri vardır.


Örneğin Ahmet çok yemek yerse, kilo alır. Ahmet tutup dünyayı yiyip 101 kiloya çıkarsa mutsuz olur. Ahmetin nümerik kilo özelliği, onun şu anki duygu durumu özelliğini etkiler. Ahmetin yemek yiyebilmesi onun yapabildiği şeyleri gösterir. Ahmet kilosundan mutsuz olup kendini aç bırakırsa, akşam daha çok acıkıp, iki tane fırın sütlaç, iki prosiyon döner ve kaymaklı ekmek kadayıfı yer ve daha çok mutsuz olur.

Nesneler birbirlerine mesaj gönderebilirler.

Ahmet’i uzun zamandan sonra gören arkadaşı, “Baba sen napmışsın, acayip kilo almışsın yea.” diyebilir. Arkadaşı Ahmet’e mesaj göndermiş olur. Ahmet’de buna sinir olup 3 ay boyunca spor salonuna yazılıp iyi bir diyet ve egzersiz programı ile fit bir hale gelebilir. Yani, nesnelerin birbirlerine gönderdikleri mesajlar, nesnelerin eylemlerini tetikleyebilirler. Bu eylemler sonucunda nesneler kendi özelliklerini değiştirebilirler.

Şimdilik bu kadar. Umarım kavramlar kafanızda biraz oturmuştur. Yazı ile ilgili düzeltme ve yorumlarınızı, sorularınızı bekliyorum.

Serinin devam yazısına şuradan ilerleyebilirsiniz:

View at Medium.com


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com

Nesnelerin Özü, Ortak Kavramlar ve Terminoloji

Alan Snyder, Yazılım ve Sistemler Laboratuvarı HPL-91–50 Haziran, 1991 Çeviri: Midori Koçak — mtkocak (at) gmail (dot) com 25.12.2016


Anahtar kelimeler: Nesneler, nesne-yönelimli-programlama, nesne-yönelimli-veritabanları, nesne-yönelimli kullanıcı arayüzleri, dağıtık sistemler, terminoloji

İlk başta nesne-yönelimli programlama dilleri için geliştirilmiş olan kavramlar birçok farklı alanda da gözümüze çarpıyorlar. Bunlar, nesne-yönelimli veritabanları, nesne-yönelimli uygulama ve birleşik platformlar, ve hatta nesne-yönelimli kullanıcı arayüzleridir. Nesne kavramları, dağıtık sistemlerde genişçe kullanıldılar ve açık sistemlerin yönetimi için olan taslak ISO Standartlarında belirgindirler. İnanıyoruz ki, “Nesne” kavramlarını gözden geçirirken, bu gibi sistemlerin çoğunda veya tamamında ortaya çıkan önemli kavramları da tanımlamış oluyoruz.

Ortak bi terminolojinin olmaması yüzünden ortak kavramları tanımlamak daha da zorlaşıyor. Ortak terminolojinin olmaması, araştırmacılar, geliştiriciler ve kullanıcılar arasındaki iletişime de engel olmakta. Bu raporda, sadece programlama dilleri için değil, bir çok alanda genişçe uygulanabilmesi için seçilmiş nesne kavramları için ortak bir terminoloji önermekteyiz. Önemli kavramları tanımlayacak, örneklere verecek ve anahtar terimleri belirleyen bir sözlük de sunacağız.

1. Giriş

Asıl olarak nesne-yönelimli programlama dilleri için geliştirilmiş kavramlar, birçok farklı alanda da ortaya çıkmaktadılar. Bunlar, nesne-yönelimli veritabanları, nesne-yönelimli uygulama çerçeveleri ve birleşik platformlar ve hatta nesne-yönelimli kullanıcı arayüzleridir. Nesne kavramları, dağıtık sistemlerde genişçe kullanıldılar ve açık sistemlerin yönetimi için olan taslak ISO Standartlarında belirgindirler.

Bu alanlar neyin nesne nesne-yönelimli olup olmadığını gösteren ortak bir kavramı paylaşıyorlar mı? İnanıyoruz ki, “Nesne” kavramlarını gözden geçirirken, bu gibi sistemlerin çoğunda veya tamamında ortaya çıkan önemli kavramları da tanımlamış oluyoruz.

Bu kavramları, bir sizi açıklayıcı cümleyi içeren tabloyla göstereceğiz. Her açıklama, çeşitli alanlardan gelen örneklerle gösterildiler. Örnekler, Smalltalk, C++ ve Common Lisp Nesne Sistemi (programlama dilleri), HP Yeni Dalga Ortamı (kişisel bilgi işlem için bir uygulama entegrasyonu ortamı), Xerox ViewPoint (Ofis İş İstasyonu), HP SoftBench uygulama geliştirme ortamı (yazılım geliştirme araçları için entegrasyon çerçevesi), Iris (veritabanı sistemi), Symbolic Dynamic Windows (kullanıcı arayüzü) ve açık sistemlerin yönetimi için uluslarası ISO taslak standardını kaynak alıyorlar. Bu sistemler az ya da çok nesne-yönelimli olarak ifade edilen sistemlerdir.

Anlatmaya yardımcı olmak için, bu sistemlerin olası faydalarını, nesne-yönelimli olmayan çözüm örnekleriyle karşılaştıran örnekler vereceğiz. Burada amacımız, nesne-yönelimli yaklaşımın değerini anlatmak değil, onu açıklamaktır. Dengeli bir değerlendirme için gereken karşı argümanları geçiyoruz. Okuyucu, alternatif yaklaşımların avantajlarının olmadığını düşünmemelidir.

Ortak bi terminolojinin olmaması yüzünden ortak kavramları tanımlamak daha da zorlaşıyor. Birbirinden farklı bir çok ekolün, nesne kavramlarını kullanması bu problemi şiddetlendirmekte. Yine de, programlama dilleri topluluğunu bir kenara bıraktığımızda dahi, bir çok farklı terim aynı kavramı, ve bazı durumlarda da, aynı terim farklı kavramları açıklamak için kullanılabilmekte. Ortak terminolojinin olmaması, araştırmacılar, geliştiriciler ve kullanıcılar arasındaki iletişime de engel olmakta.

Bu raporsa, nesne kavramları için ortak bir terminoloji önermekteyiz. Terminoloji, sadece programlama dillerine değil, aynı zamanda farklı alanlara da uygulanabilmeleri için özellikle seçilmiştir. Bu nedenle, nesne-yönelimli programlamadan kaynaklanan birtakım yerleşik terimler de uygunsuz sayılmaktalar. Önemli kavramların açıklanması, anahtar terimleri açıklayan sözlükte yeralmakta.

Bu çalışma, Hewlett-Packard içinde kurumsal iletişimi geliştirmek amacıyla nesne kavramları için ortak terminoloji yaratma çabasından ortaya çıktı. En önce ilgili teknolojileri karşılaştırmak ve karakterize etmek için temel olacak çekirdek kavramları tanımladık ve açıkladık. Kavramlı tanımladıktan hemen sonra, bu kavramlar için terimleri seçtik. Çalışma, Obje Yönetim Grubu (Object Management Group) için soyut bir nesne modeli geliştirilmesi sürecinde rafine edildi ve hali hazırda ANSI tarafından sponsor olunan, nesne modellerini standartlaştırma çabalarında da kullanılmaktadır.

Önemli Kavramlar

  • Bir nesne hizmetler tarafından karakterize edilen bir soyutlamanın vücut bulma halidir.
  • İstemci, nesnelerden hizmetler talep eder. a) İstemciler talep bildirirler. b)Nesneler kapsüllenmişlerdir. c) Talepler işlem belirtirler. d) Talepler nesneleri tanımlayabilirler.
  • Yeni nesneler yaratılabilirler.
  • İşlemler jenerik olabilirler.
  • Nesneler sundukları hizmetlere göre sınıflandırılabilirler (arayüz hiyerarşisi)
  • Nesneler, uygulanımları (implementation) paylaşabilirler. a) Nesneler ortak bir uygulanımı paylaşabilirler. (bir çok örnek) b) Nesneler kısmı uygulanımları paylaşabilirler. (uygulanım hiyerarşisi veya delegasyon)

2. Başlıca Kavramlar

Bu bölümde bir nesne sisteminin başlıca kavramları tanımlanmaktadır. Bir nesne sistemi, nesne adı verilen, istemcilere hizmet sunulmasında önemli sol oynayan varlıklara sahiptir. İstemcilerin ve hizmetlerin kesin doğası belirlenmiş nesne sistemine bağlıdır. Genel olarak, bir istemci, bir kişi ya da program olabilir ve bir hizmet istemcinin talebine bağlı olarak gerçekleştirilen herhangi bir aktivite olabilir. Başlıca kavramlar nesne sistemlerinin ortak karakteristiklerini belirlerler. (Wegner ve Thomas tarafından yazılan makaleler, benze materyalleri daha öğretici tarzda sunuyorlar)

Bir nesne hizmetler tarafından karakterize edilen bir soyutlamanın vücut bulma halidir.

Bir nesne bir soyutlamanın vücut bulma halidir.

Bir nesne, açıkça istemcileri için anlamlı olan bir soyutlamanın vücut bulmuş halidir. Bir nesne verilerle ilgili olsa da, sadece bir veri yapısı veya 0,1’ler koleksiyonu değildir. Verinin amacı, bilgiyi sunmaktır.

Yarar: İstemciler anlamlı varlıkları manipule ederler. İstemciler veriyi sunmak ya da yorumlamaktan sorumlu değildirler.

Tezat: Nesne içermeyen bir model, verilerin sadece bir bit dizisi olduğu, bit okuyan veya yazan programlar tarafından örtük olarak yorumlanmayla sınırlı olduğu ve farklı programların farklı yorumlamalar yaptığı bir sistemdir. Bu modelde, müşterilerin verilerin nasıl yorumlanacağını bilmeleri gerekir. Ayrıca, veriler yanlış programa verildiğinde, yanlış yorumlanabilir.

Örnek: Dokümanlar, dizinler ve grafikler gibi aşina olunan soyutlamalara denk gelen nesneler, ViewPoint ve HP NewWave ortamının kullanıcılarına sunulmaktadır.

Örnek: Smalltalk programcıları, diziler ve sözlükler gibi aşina oldukları programlama soyutlamalarını destekleyen nesnelere sahiptirler.

Karşıt örnek: Unix içerisinde, sıradan bir dosya, yorumlanmamış bir byte dizisidir. Dosyanın yorumlanması uygulama programlarına bırakılmıştır. Aynı dosya bir C derleyicisi tarafından C kaynak kodu olarak algılanabilir ya da grep (bir metin arama aracı) programı tarafından uzun bir metin dizisi olarak algılanabilir. Farklı dosyaları anlamlı soyutlamalarla ilişkilendirmek için Dosya isimlenddrme kuralları gibi (örneğin foo.c adlı bir dosyanın C kaynak kodu anlamına gelmesi gibi) farklı teknikler kullanılır.

Ayrıntılandırma: Soyutlamalar bir hiyerarşi oluşturarak bir sistemin her düzeyinde ortaya çıkar: daha üst düzey soyutlamalar, daha alt düzey soyutlama terimleriyle uygulanmaktadırlar. Bir dosya, kalıcı bir depolama için bir soyutlamadır ve gerçek depolama cihazlarından daha yüksek seviyededir. Ancak birçok dosya, örtük olarak daha yüksek seviye bir soyutlama uygulamaktadır. Bir C programı eya bir doküman gibi. Çoğu Unix kullanıcısı için anlamlı olan bu üst düzey soyutlamalardır.

Bir nesne hizmet sağlayıcısıdır

Nesne tarafından gerçeğe dönüştürülen bir soyutlama, istemciler tarafından talep edilebilen bir hizmetler kümesi tarafından karakterize edilir. Bir hizmet, veriye erişebilir ya da onu değiştirebilir, ve gözlemlenebilir etikleri ortaya çıkarabilir. Hizmet tarafından değiştirilebilen veriye durum (state) denir.

Ayrıntılandırma: Hizmetler somutlaştırılmış soyutlama için uygundur. Hizmetler genellikle karmaşıktırlar; veriler üzerinde keyfi değişikler içerebilir ve diğer nesneleri etkileyecek ek hizmetler talep edebilirler. Sadece adlandırılmış öz niteliklerden oluşan, okunabilen ve yazılabilen bir kayıt, hizmetleri basit okuma ve yazma işlemleri olan ve durum olarak öz niteliklere sahip olan basit bir nesne formudur. Durum (state) belli nesnelerle alakalı veya alakasız olabilir veya farklı nesneler tarafından paylaşılıyor olabilir.

Yarar: Karmaşık sistemler tümleşik kısıtlamaları korumak adına özenle tasarlanmış olabilirler. Eğer sadece ilkel hizmetler sunuluyorsa, istemciler kendiliğinden bu hizmetleri daha karışık hizmetlerde bütünleştirmek zorunda kalabilirler ve bu da muhtemel hatalara sebep olabilir.

Örnek: Bir sözlük nesnesi, istemci için isimden değer döndüren bir hizmet sunar. Bu hizmetin uygulanması, sıralı ikili ağaç gibi karmaşık bir veri yapısının inşa edilmesini ve değiştirilmesini gerektirebilir. Altta yatan veri yapısının hatalı bir şekilde değiştirilmesi, ikili ağacın hatalı sıralanmasına ve sözlük hizmetlerinin hatalı davranmasına sebep olabilir.

Örnek: Dağıtık bir ortamda bir yazdırma kuyruğu nesnesi, birden fazla kullanıcının metin dosyalarının yazdırma kuyruğuna ataması hizmetini sunar. Bu hizmet, herhangi bir müdahele olmadan taleplerin eşzamanlı olarak sunulabildiği bir işlem mekanizması kullanılarak uygulanabilir. Eğer uygulamalar sadece düşük seviye okuma ve yazma işlemleri sunuyorlarsa, müdahele edilmemeyi garanti etmek adına bu düşük seviye hizmetlerin sıralı olarak birleştirilmesi gerekebilir. Bu durumda, yazdırma kuyruğu güvenirliği garanti edemez çünkü eşzamanlı taleplerin doğru işlenmesi, ayrı ayrı uygulamaların doğruluklarına bağımlıdır.

Karşıt örnek: Standart Unix Posta Teslimat hizmeti, kullanıcının posta kutusu dosyasına belirli bir protokolü izleyerek erişen uygulamalara dayalıdır. Bu protokol, bir kilit dosyası yaratmayı ve test etmeyi gerektiren belirli ve sıralı adımlara ihtiyaç duyar. Eğer bir uygulama, yeni bir postayı, posta kutusu doyasından çıkarırken bu protokolü izlemede hata yaparsa, eş zamanlı iletilen mesajlar kaybolabilir veya bozulabilirler.

İstemciler nesnelerden hizmetler talep ederler.

İstemciler talep bildirirler.

İstemciler nesnede vücut bulmuş soyutlamaya saygı duyarlar. Veriye direkt olarak erişmek yerine, istemciler nesnelerle ilişkili hizmetlere taleplerini bildirirler. Bir talep, talep edilen hizmeti gerçekleştirecek kodun çalışmasını sağlar. İstemci, kodun nerede ve nasıl çalıştığı ile değil, sadece istediği hizmetin çalışmasıyla ilgilidir. Bir talebin davranışı, istenen ve gerçekleştirilen hizmetin görünür etkisidir. (sonuçları ile beraber)

Yarar: İstemciler bir hizmetin gerçekleşmesi için hangi kodun çalışması gerektiğini hatırlamak zorunda değildirler. İstemciler hatayla yanlış kodu çalıştıramazlar.

Örnek: ViewPoint ve HP NewWave kullanıcıları belirli bir nesneyi değiştirmek için hangi uyuglamanın çalışması gerektiğini hatılamak zorunda değildirler; sistem uygun uygulamayu, kullanıcı taleplerine cevap olarak çağıracaktır. (örneğin, bir ikona yönelen fare harekerleri ile tetiklenmiş olabilirler)

Örnek: Bir Smalltalk programı, bir nesneye mesaj göndererek hizmet talebinde bulunur. Nesne, istenen hizmetin nasıl gerçekleşeceğinden sorumludur. Smalltalk içindeki tek tür hatası, istenen hizmetin mevcut olmamasıdır. Yanlış veriye kod uygulanamaz.

Yarar: İstemcileri, nesnenin uygulanmasından izole ederek, nesnenin uygulanmasını, istemciyi değiştirmeye gerek kalmadan değiştirmek mümkündür.(Hizmetlerin, istemcilere değişmez göründüğü varsayılır)

Örnek: Nesne-yönelimli programlamayı kullanan bir programcı, sözlük nesnelerini uygulamak için, bir çok durumda, dramatik olarak performansı iyileştiren yeni bir teknik keşfeder. Bu teknik, sıralı bir ikili ağaç yerine, hash tablosu kullanmaktadır. Sözlük nesnesinin yeni uygulanımı, veri formatı ve hizmetlerin uygulanımı farklı olsa da, eskisinin aynısı hizmetleri aynı şekilde sunmaktadır. Yeni sözlük uygulanımı, yeni nesne kütüphanesi yayınlandığında eskisinin yerini alır. İstemci kaynak kodunun değişmesine veya yeniden derlenmesine gerek yoktur.

Örnek: Bir HP SoftBench yazılım geliştirme ortamı kullanıcısı, standart SoftBench düzenleyicisi yerine GNU Emacs düzenleyicisi kullanmaya karar verir. GNU Emacs düzenleyicisi, SoftBench düzenleyicisi gibi (diğer uygulamalar için) aynı hizmetleri desteklediği için, düzenleyici hizmetine talep eden diğer uygulamalar, GNU Emacs düzenleyicisini kullanarak çalışmaya devam edeceklerdir.

Örnek: HP SoftBench ortamına, dış bir araç, HP Encapsulator programı, istemci taleplerini karşılayacak olan araç için sarmalayıcı yaratılarak, gömülebilir.

Örnek: Dış bir veritabanına, Iris veritabanına, istemcilerden gelen talepleri, uygun dış veritabanı çağrılarına dönüştüren dış işlevlerin sağlanmasıyla erişilebilir. (Iris içindeki dış işlev, konvansiyonel bir programlama dili kullanılarak yazılmış bir programdır.)

Nesneler Kapsüllenmişlerdir.

Bir istemci, nesnelere sadece hizmet talepleri göndererek erişebilir. İstemcilerin, nesnelerle bağlantılı olan verilere erişmeleri ve değiştirmeleri engellenir.

Yarar: Verilerle direk ilişkiye geçilmesini engelleyerek nesnelerin birtakım tümleşik kısıtlamalara uymaları garanti edilmektedir. Ayrıca istemcilerin de nesnelerin uygulanımlarından etkilenmemeleri de garanti edilmektedir.

Örnek: Smalltak ve C++ gibi nesne-yönelimli programlama dillerinde, bir istemcinin, bir nesnenin anlık özel değişkenlerine (private instance variable) doğrudan erişeleri, normal kullanımda engellenmektedir. (Ancak iki dilde de olağandışı durumlarda bu kısıtlamaların etrafından dolaşmayı sağlayan birtakım yapılar mevcuttur)

Talepler, işlemleri tanımlarlar.

Bir talep, bir hizmetin gerçekleştirilmesini, bir işlem tanımlayarak işaret eder. Bir işlem, bir hizmet belirten ve tanımlanabilen bir varlıktır.

Örnek: HP NewWave masaüstü, kullanıcının bir takım yollarla, örneğin, -menü öğelerini seçmek ya da ikonları çöp kutusuna ya da yazıcı ikonun sürükleyip bırakmak gibi- işlemleri tanımlamasına izin verir.

Örnek: C++ dilinde, bir işlem, belirli bir sınıfta, belirli üye metoduna, mevcut olan öz niteliklerin tür tanımlamaları yapılarak isim verilmesiyle tanımlanır. (öz niteliklerin tür tanımları, aşırı yüklenmiş metodları çözmek için kullanılır) Eğer iki sınıf aynı metod ismini tanımlıyor ve metod ortak bir ata sınıftan miras alınmış sanal bir metod değilse, o zaman metodlar iki farklı işlem olarak dikkate alınır.

Örnek: Common Lisp Nesne Sisteminde, bir işlem, belirli bir jenerik metod nesnesi ile tanımlanır. Farklı bağlamlardaki aynı metinsel isim, farklı jenerik metod nesnlererine işaret edebilir ve bu durumda da farklı işlemler olarak dikkate alınırlar.

Örnek: Açık sistemlerin yönetimi için taslak ISO standardında, bir işlem, global olarak bir kayıt otoritesi (registration authority) tarafından atanan eşsiz bir belirleyici (unique identifier) ile tanımlanmaktadır.

Talepler, nesneleri tanımlayabilirler.

Bir talep, ilişkili öz niteliklere sahip olabilir ve bir hizmet bir veya birden daha fazla sonuç döndürebilir. Bir öz nitelik veya bir sonuç bir nesneyi tanımlıyor olabilir. (Çoğu sistemde her talep için varolan tanımlanmış öz nitelik, talebi gerçekleştirmek için varolan nesneyi tanımlasa da, başka ihtimaller de mevcuttur. -Klasik ve jenerik nesne modelleri tablosuna bakınız.)

Bir nesne doğrudan ve güvenilir olarak tanımlanabilir. Nesne tanımlaması, nesnenin tanımlanması bakımından değil, adlandırılamsı bakımından doğrudandır. Nesne tanımlaması, güvenilirdir çünkü, bir tanımlayıcının tekrar edilmesi, her zaman aynı nesneyi işaret edecektir. (Uzay zamanın pragmatik sınırlarına özne olarak) Nesneyi tanımlayan bir değer, nesne referansı olarak adlandırılır.

Ayrıntılandırma: İlişkili bir duruma sahip olan bir nesnenin, durum değişkenlerinin o anki değerlerini aşkın bir kimliği vardır; iki nesne aynı anlık duruma sahip olabilir, biri durumunu değiştirebilir ve diğeri değişmeden kalabilir. Bu gibi nesnelerde, nesne kimliği bir gerekliliktir; nesnenin (öz nitelik terimleri kullanılarak) tanımlanması elverişsiz olacaktır. Bir nesnenin açıklamasını kullanmak, belirgin bir nesne kimliği öz niteliğinin takdim edilmesini gerektirir, ki bu durum, ek değişmez ve eşsiz tümleşik kısıtlamalar getireceğinden avantajsızdır.

Yarar: İstemciler, nesnelere işaret edebilme yeteneklerine bağlı olabilirler. İstemciler, işaret ettikleri nesnenin, (nesne varolduğu sürece) doğru nesneye işaret edip etmemesi veya tamamen başarısız olması konusunda endişelenmek zorunda değildirler.

Örnek: İkonlara sahip olan bir kullanıcı arayüzü, kullanıcıların nesneleri ekran üzerindeki görsel temsiller kullanarak işaret etmelerini sağlar. Bu kullanıcı arayüzü görsel temsil kullanarak altta yatan veriye ulaşılmasını sağlar. İkonlardan veriye ulaşılması bir harita kadar güvenilir olduğu için, kullanıcılar o ikonların doğrudan veri olduklarını düşüneceklerdir.

Klasik ve Genelleştirilmiş Nesne Modelleri

En güncel nesne sistemleri, klasik nesne modeline sahiptirler. Klasik nesne modelinde, her talep hedef nesneyi tanımlayan açık bir öz niteliğe sahiptir. Hedef nesne, talebin yorumlanmasını kontrol etmektedir. Klasik nesne modelinde bir talep mesaj olarak adlandırılır ve işlendiği hedef nesnesine ulaştığı anda görülmeye başlanır. Örneğin, bir yazıcıda bir doküman yazdırmak için varolan bir talep, yazıcı nesnesine gönderilen belge yazdırma talebi olabilir.

Genelleştirilmiş nesne modeli ise, talebin hedef nesneyi açıkça belirtmesini gerektirmez. Bir istek, sıfır veya daha fazla öz niteliğe sahip olabilir, bunlardan herhangi biri nir nesneyi işaret edebilir. Bir talebin yorumlanması, bu öz niteliklerin biri veya hepsine bağlı olabilir; özellikle belirtilen bir öz nitelik yoktur. Hizmet bu işaret edilen nesnelerden biri veya 3. parti tarafından sunuluyor olabilir. Örneğin, belirli bir yazıcıda, belirli bir dokümanı yazdırma talebi, özel bir çeşit belgeyi, yine özel bir çeşit yazıcıda yazdırmak için oluşturulmuş bir işlem tarafından halledilebilir. Bu işlem, sadece bu özel çeşit belgeyi yine özel çeşit yazıcıda çalıştırma talebi geldiğinde çalıştırılacaktır.

Genelleştirilmiş nesne modeli, klasik nesne modelini, özel bir durum olarak içermektedir. Bir mesajın klasik olarak bir nesneye gönderilmesi, hizmetin bir nesne tarafından belirli bir öz nitelikle ve klasik modelde ayrık bir öz nitelik kullanılarak sunulduğu, genelleştirilmiş talebin eşitidir. Genelleştirilmiş nesne modeli, bir talebin yorumlanmasının, kesin olarak, belirlenmiş bir işleme dayalı olduğu sıradan işlemleri özel bir durum olarak da içerir.

Genelleştirilmiş nesne modelleri, Common Lisp Nesne Sistemi ve Irıs veritabanlarında kullanılmaktadır. Genelleştirilmiş Modellerin nerelerde ortaya çıktıkları henüz tamamen bilinmese de, uygulama bilgisinin özenle parçalanamadığı ayrık nesneler arasında, daha genel bir nesne modelinin gerekliliği açıktır.

Karşıt Örnek: Standart Unix kullanıcı arayüzü, dosyalara işaret etmek için metinsel isimler kullanır. Metinsel isim, dizin hiyerarşisi kullanılarak asıl dosyaya işaret eder. Bu işaretleme, her an dosyalar taşınabildiği ve dizin yapısı yeniden düzenlenebildiği için güvenilir değildir. Örneğin, bir kullanıcı, dizini listelediğinde, bir foo dosyası görüntüleniyorsa, kullanıcı bir sonraki listelemede foo isminin yine aynı dosyayı mı, yoksa farklı bir dosyayı mı işaret ettiğinden emin olamaz. (Unix çekirdeği içinde, inode sayıları, güvenilir bir şekilde dosyaları tanımlamak için kullanılmaktadır.)

Örnek: Unix’in bir dosya isminin güvenilir olarak bir dosyayı işaret edemedii dizin listelemesinin aksine, Dynamic Windows’da, sistem hangi dosyanın (nesnenin) ekrandaki hangi metine işaret ettiğini hatırlar. Eğer listeleme bir foo dosyası gösteriyor ise, kullanıcı ekrandaki foo metnine tıkladığı anda, dosya ile yapabileceği işlemleri gösteren bir menu ortaya çıkar. Dosya yeniden adlandırılsa bile bu işlem çalışmaktadır.

Örnek: HP NewWave ortamında, bir uygulama belge nesnesinden, grafik nesnesine bir bağlantı oluşturabilir. Bu bağlantı, kullanıcı grafik nesnesini başka bir dizine taşısa dahi varolmaya devam edecektir. Belge başka bir sisteme kopyalandığında, grafik nesnesi de aynı zamanda kopyalanacaktır.

Karşıt Örnek: Unix içinde, bir C kaynak kodu dosyası, başka dosyalara isimleriyle atıfta bulunabilir. Eğer dizin yapısı yeniden düzenlenirse, dosya içinde atıfta bulunulan “bağlantı” da bozulabilir. Dosya ismi yanlış bir dosyaya işaret edebilir ya da işaret ettiği yerde dosya mevcut olmayabilir.

Örnek: C++’da nesneler, işaretçiler ve referanslar kullanılarak tanımlanmaktadır. Bir işaretçi veya referans, işaret ettiği nesne varoldu sürece geçerlidir.

Karşıt örnek: İlişkisel bir veritabanında, bir değişkenler demetine (tuple) (bir sorgu içinde) demetin öz niteliklerini tanımlayan değer tanımları vasıtasıyla erişilebilir. Farklı demetler (Tuple), eğer öznitelikler değiştiriliyorsa, aynı tanım ile farklı zamanlarda erişiliyor olabilir. (Bir demete (tuple) güvenilir erişim, sadece demet (tuple) içerisinde anahtar öz nitelikler varsa yapılabilir. Anahtar öz nitelikler, birbiriyle ilişkisi olan değişken demetlerini (tuple) eşsiz biçimde tanımlayan değişmez öz niteliklerdir.

Karşıt örnek: HP SoftBench Ortamında, talep mesajının hedefi, bir araç sınıfından, bir mesaj isminden ve özel bir veri dosyasını tanımlayan bir metinden oluşan açıklama vasıtasıyla tanımlanmaktadır. Bir araç aktivasyonu, bu değerleri, her araç tarafından belirtilen karşılık gelen değerlerle eşleştirerek istenen hizmeti gerçekleştirmek için seçilir. İstemci, aynı aracın ya da araç aktivasyonunun, her seferinde istemci mesajı tarafından verilen belirli tanımlama cevabını vereceğini varsayamaz. Gerçekte, istemci, herhangi bir araç aktivasyonunun cevap vereceğini veya en fazla bir araç aktivasyonunun cevap vereceğini varsayamaz.

Yarar: Doğrudan nesnenin tanımlanması, normalde, nesneyi, kendi açıklamasına bağlı olarak tanımlamaktan daha verimlidir.

Yeni nesneler yaratılabilirler.

İstemci varolan nesnelerden farklı olan yeni nesnelerin yaratılmasını talep edebilir.

Yarar: Zamana bağlı değişen davranışa sahip olan nesneler, birden çok istemcilerin etkileşimine izin verirler. Yeni nesnelerin yaratılması, istemcilerin yanlışlıkla aynı nesneyi paylaşarak çatışmalarını önlemek için kullanılır. İstemciler, yeni yaratılan nesnelerin ayrıklığından sorumlu değildirler.

Örnek: Bir istemci programı yeni ve boş bir sözlük nesnesi yaratır. Yeni sözlük nesnesi, tüm diğer sözlük nesnelerinden, hatta boş olanlardan dahi ayrıktır. Eğer istemci, bu sözlük nesnesinin durumunu, bir isim ve bağlantılı değer girerek değiştirirse, diğer sözlük nesneleri etkilenmeyeceklerdir.

Örnek: Bir ViewPoint kullanıcısı, yeni bir belge yaratır. Örneğin, varolan bir belgeyi kopyalar. Yeni belge, ekranda yeni bir ikon olarak, diğer tüm belgelerden görünür olarak ayrıktır. Belgenin eşsizliği sistem tarafından garanti edilmektedir. Kullanıcı, belgeye herhangi bir eşsiz isim atamak zorunda değildir.

İşlemler jenerik olabilirler.

Bir hizmetin, farklı nesneler için, gözle görünür biçimde farklı davranışları olan, (benzer amaçları paylaşıyor olsalar dahi) farklı uygulanımları (farklı kodu) olabilir. Bir istemci her nesne veya hizmet için aynı talepleri bildiriyor olabilir. (Talepler ortak bir işlemi tanımlarlar) ve her ayrı talep için, uygun bir uygulanım seçilir. Verilen bir hizmet için farklı uygulanımların olmasında bir sayı sınırı yoktur.

Birden çok uygulanımı bulunan işleme, jenerik işlem adı verilir. Jenerik işlemleri talep eden istemcilerin kendileri de, farklı nesne çeşitleri üzerinde ortak bir aktivite gerçekleştirebilmeleri bakımından jenerik olabilirler.

Bir hizmeti gerçekleştirmek için kod seçimi (bağlama) (binding), talep içinde tanımlanmış nesnelere dayalıdır. Genel olarak, nesnelerin tanımlanması, istek bildirildiği and meydana gelmektedir, bu sayede kod seçimi, tam o anda meydana gelebilir. (dinamik bağlama) (dynamic binding) Bazı zamanlarda, kod seçimi, yürütme zamanından önce bilinen etkenlere bağlıdır, o zaman kod, programın derlenme ya da linking anında seçilebilir. (static binding) (static binding)

Yarar: Jenerik işlemlerin bir yararı, sistemin şeffaf bir şekilde bir hizmetin çoklu uygulanımlarını sunmasıdır. Bu özel durumda, uygulanımlar, gözlemlenebilir şekilde eşit etkiler üretirler. Bir hizmeti talep eden istemcinin, farklı nesneler için farklı kodların çalıştığını bilmesine gerek yoktur.

Örnek: Bir heterojen dağıtık sistem, farklı donanım mimarilerinde uygulamanın farklı versiyonlarını sunuyor olabilir. İstemci uygulaması, basitçe, hedef nesnenin yere bağlı olarak hangi kodu çalıştıracağını bilmeden taleplerde bulunur.

Örnek: Modemleri yönetmeye yarayan bir ağ yönetim uygulaması, sistemdeki modemlerin yerine bağlı olarak farklı kodların yürütülebileceğini bilmeden, basitçe modemlere isteklerde bulunur.

Örnek: Sözlük nesnelerinin yeni bir uygulanımı, farklı bir isim altında kütüphaneye eklenmiştir, bu sayede eski uygulanım sistemde varolmaya devam etmektedir. Yeni uygulanım, bir çok durumda daha yüksek performans sunmaktadır, ancak bazı kullanım desenlerine bağlı olarak eski uygulanımın bazı koşullarda daha iyi performansa sahip olduğu bilinmektedir. Sözlük nesnelerini kullanan bir istemci program, beklenen kullanıma bağlı olarak, yarattığı her sözlük için daha uygun uygulanımı seçmek üzere değiştirilmiştir. Sözlük nesnelerini kullanan program parçaları değiştirilmemiştir, iki uygulanımla birlikte çalışırlar.

Yarar: Jenerik işlemlerin bir diğer yararı da kodun daha genel olmasıdır, bu sayede kodun yeniden kullanılabilirliği artar. Bu durumda, jenerik işlemin, farklı uygulanımları gözle görülür biçimde farklı etkiler üretebilirler.

Örnek: Karşılaştırma hizmeti sunan bir nesneler kümesini sıralayacak bir sıralama modülü sunulabilir.

Yarar: Kullanıcı ara yüzleri örneğinde, kullanıcılar, bir çok durumda standart bir zihinsel model kullanabilirler.

Örnek: ViewPoint, atanmış işlev tuşları kullanarak, herhangi bir tür nesne üzerinde çalıştırılabilecek jenerik komut kümeleri sunmaktadır.

Örnek: HP NewWave ortamının kullanıcılarının, herhangi bir tür nesneyi yazdırmak için, sadece nesneyi yazıcı ikonunun üzerine sürükleyip bırakmayı hatırlamaları yeterlidir.

Yarar: Jenerik işlemler, açık sistemlerin gerçekleştirimlerini kolaylaştırmaktadır. Açık bir sistem, yeni nesnelerin dinamik olarak ortaya konduğu ve bu sayede yeni nesnelerin, varolan istemcilerin kodları değiştirilmeden çalıştırıldığı sistemlerdir. Varolan istemciler, istemci taleplerini destekledikleri için yeni yaratılmış nesneleri kullanabilirler. Açık bir sistem yeni yazılım bileşenlerinin yaratılmasına ve sistem çalışırken yüklenmesine olanak verir. Açık sistemlerin evrilmeleri ve geliştirilmeleri daha kolaydır.

Nesneler sundukları hizmetlere göre sınıflandırılabilirler.

Nesneler bağlı olan hizmetler, arayüz şeklinde açıklanabilirler. Bir arayüz, nesnenin istemci tarafından nasıl kullanıldığını, nesneyi öz nitelik olarak tanımlayan muhtemel istekler kümesini tanımlayarak açıklar. Bu tanımlama, diğer istek özniteliklerinin mantıklı değerlerini ve her taleple ilgili muhtemel sonuçları içerebilir ve ayrıca taleplerin davranışlarını da açıklayabilir. Nesneler sundukları hizmetlere göre, yani sundukları arayüzlerin terimleriyle sınıflandırılabilirler.

Yarar: Nesnelerin hizmetlerine dayalı sınıflandırması, nesnelerin anlaşılmasını kolaylaştırmak için nesneleri organize etmenin bir yoludur. Nesnenin bir sınıflandırması, nesneden istemci tarafından beklenen hizmetleri açıklamak ve derleme zamanında nesnelerin hatalı kullanımlarını kontrol etmek için de kullanılabilir. (örneğin nesnenin desteklemediği bir işlemin gerçekleştirilmesinin talep edilmesi gibi tür hataları)

Örnek: HP NewWave ortamının bir kullanıcısı, menülerden istifade ederek bir nesneyle ilgili geçerli işlemleri görsel olarak belirleyebilir. Seçili nesne için geçerli olmayan işlemler, uygulanabilir işlemlerden ayırt etmek için gölgeli olarak gösterilir.

Karşıt örnek: Bir Unix kullanıcısı, ayrı ayrı her dosya için hangi komutların uygulanabileceğini hatırlamak zorundadır. Eğer kullanıcı bir hata yapar ve yanlış dosya türü için yanlış komutu çalıştırırsa, bekleyeceği en iyi şey komutun dosyanın hatalı türde olduğunu tespit ederek bir hata mesajı vermesidir. Kullanıcının verilen bir dosya için uygun komutları bilebilmesinin doğrudan bir yolu yoktur.

Örnek: Bir C++ sınıfı, nesnenin örnekleri (instance) tarafından sunulan hizemetleri, her örnekteki üye metodları listeleyerek tanımlar. Ayrıca statik tür kontrolü amacı için, bir tür olarak hizmet eder. (Bir C++ sınıfı, sınıfın örneğinin sunduğu hizmetleri açıklamaktan daha çok iş yapar, ayrıca sınıfın uygulanımlarını da tanımlar.)

Örnek: Açık sistemlerin yönetimi için taslak ISO Standartlarında, bir sistem yönetim nesnesi, bir nesnenin öz nitelik ve eylemleri belirtilerek tanımlanır. Geliştiriciler, sınıfı nesneye erişen uygulamalar yazmak için kullanırlar.

Bir nesne, farklı bir nesnenin sunduğu hizmetlerin bir altkümesini sunabilir, bu da hiyerarşik sınıflandırmaya yol açar. (Hiyerarşi terimi, birçok nesne sistemi daha genel sınıflandırma yapılarını desteklemelerine rağmen sıklıkla gayri resmi bir şekilde kullanılmaktadır.) Arayüz hiyerarşisi aynı zamanda tür hiyerarşisi olarak da kullanılabilir, örneğin, istek öz niteliklerinin mantıklı değerlerini tanımlamak için.

Bağlantılı kavramlar.

Nesne sistemleri incelememizde, belirli kavramlar, zorunlu olmayan bir şekilde nesne fikrine bağlı olarak yeterli sıklıkla karşımıza çıkarlar. Belki de gelecekte düşüncelerimiz evrimleştikçe, bu çağrışımlar daha da güçlenecek ve nesnelerin özünün bir parçası olarak kabul edilecekler.

Olay bildirimi (Event notification). Bir istemci, durum değişikliği gibi, bir nesneyle bağlantılı bir olay ve koşula olan ilgisini kayıt altına alabilir ve olay veya koşul meydana geldiğinde bildirim alabilir.

Olaya dayalı kontrol yapısı (Event-driven control structure). Bir program yapısı, gelen olayları bekleyen ve onları uygun işleyicilere sev eden üst seviye olay örgüsü ile karakterize edilir.

Sunum-semantik bölünmesi (Presentation-semantic split). Bir program yapısı, soyut bir bilgiyi (semantik bir nesne) modelleyen ve bu tarz bilgiyi kullanıcıya sunan (bir sunum nesnesi) farklı nesnelerin kullanılmasıyla karakterize edilir. Tekil bir semantik nesne, birden fazla, bağlantılı, farklı sunum nesnelerine sahip olabilir. Örneğin, finansal verilerin, pasta diyagramı ve çubuk diyagramı ile aynı anda gösterilebilmesi gibi.

Bileşik nesneler (Composite objects). Bir bileşik nesne, birden fazla farklı nesnenin birbirleriyle birleştirilmesi (combining) veya bağlanması (linking) ile oluşur. Bu sayede bileşik nesne üzerinde tek bir nesne gibi değişiklik yapılabilir. (kopyalanabilir ya da taşınabilir.) Örneğin, bir belge nesnesi, belge içindeki bir figürde bulunan bir grafik nesnesi ile bağlantılı olabilir. Bir sıcak bağlantı (hot link) grafiğe bağlı olan veri değiştiği anda, belgenin güncellenmesini sağlar.

Aktif nesneler (Active objects). Aktif bir nesne, bir istemci tarafından talep edilmeden, hesaplamayı (computation) kendiliğinden başlatabilir. Aktif bir nesne, eşzamanlı bir işlemdir; kendine ait bir etkinliğe ve kontrol için iş parçacığına sahiptir. (thread of control)

İlişkiler (Relationships). Bir ilişki birden fazla nesneyle, ayrı ayrı olmadan alakalı olan bilgidir. Örneğin, bir çalışan ilişlisi, kurumlar ve kişiler arasındaki ilişkiyi tanımlamaktadır.

Yarar: Bir arayüz hiyerarşisi bir istemcinin, birden fala çeşit nesne üzerinde çalışabileceğini, jenerik işlemler için talep bildiriminde bulunarak gösterir.

Örnek: C++ sınıf türetme üzerine kurulu bir tür hiyerarşisi tanımlar: bir C++ sınıfının örneği, (referans veya işaretçi vasıtasıyla), bir temel (public) sınıf beklendiğinde, herhangi bağlamda kullanılabilir. C++’da sınıf türetme, bir sınıfın örneği, temel sınıf tarafından tanımlanmış tüm hizmetleri sunulduğu anda garanti edilmiş (semantik olarak değil, sentetik olarak) olur.

Örnek: Dynamic Windows kullanıcı arayüzü, sunum türleri için kullanıcıya verilen bağlam için kabul edilebilir nesne kümelerini karakterize eden bir hiyerarşi tanımlamaktadır. Örneğin, bir işleneçten (operand) bir komuta. (command)

Örnek: HP NewWave ortamı, araçlar ve kullanıcı nesneleri ayrımı gibi, ortak hizmetlere bağlı olarak, kavramsal bir hiyerarşi tanımlamaktadır. Kullanıcıların bu ayrımları anlamaları, daha basit bir zihinsel model sağladığı için, kendilerine yarar sağlar.

Nesneler uygulanımları paylaşabilirler.

Nesneler ortak bir uygulanımı paylaşabilirler.

Bir nesneyle bağlantılı olan hizmetlerin uygulanımı, genel olarak amaca uygun bilgiyi sunmak için varolan verinin biçimini ve hizmetleri gerçekleştiren kodları hep birlikte tanımlamaktadır. Sunulan mekanizmalar, genelde, birden fazla nesnenin, ortak bir uygulanımı (implementation) paylaşmasına olanak sağlar. Ortak bir uygulanımı paylaşan nesneler, özdeş veri biçimlerini sahiptirler ve yürütlecek kodu da ortak kullanırlar, ancak, her nesne tipik olarak, kendi veri kopyasına sahiptir. Herbir nesne, ortak uygulanımın bir örneği (instance) olarak düşünülebilir.

Yarar: Ortak bir uygulanımı, birçok nesne boyunca paylaşmanın, apaçık şekilde, kaynak kodunun kopyalanmasını azaltması bakımından (ayrıca bu durum değişikliklerin elle yayılmasını engellemesi bakımından kodun bakımını da kolaylaştırır) ve yürütülebilir kod büyüklüğünü azaldır (yürütülenilen kod (executable code) ortak kullanılabildiği sürece) yararı vardır. Bir uygulanımdan birden fazla örnek oluşturabilmenin mümkün olması uygulanımı da daha kullanışlı yapar.

Örnek: Smalltalk ve C++ dillerinde, nesne, sınıfın örneğidir; bir sınıf, her örnek için veri biçimini ve aynı zamanda her örnek tarafından sunulan hizmetleri uygulayan (implementing) işlemleri (procedure) belirlemektedir.

Karşıt örnek: C’de tek bir veri soyutlamasının, gizli (private) değişmez (static) veriler ile çalışan dış metod kümesini tanımlayan bir kaynak kodu dosyası ile uygulanımı gerçekleştirilebilir. Ancak, bu tanımlama, aynı davranışa sahip birden faza varlığın desteklenmesi için örneklenemez.

Nesneler kısmı uygulanımları paylaşabilirler

Benzer davranışa sahip nesnelerin, ortak uygulanımlarının belli kısımlarını paylaşmasını sağlayan mekanizmalar sıklıkla sağlanmaktadır.Örneğin, uygulanımın mirası (implementation inheritance), diğer nesne uygulanımlarını genişleterek veya rafine ederek bir nesne uygulanımının artımlı inşasını destekler.

Örnekler

Aşağıdaki örnekler istekleri göstermektedir. Bir istek, (etkisinin açıklaması ile birlikte) öz nitelikler tarafından takip edilen bir işlem olarak gösterilir. S ismi, bir yığın nesnesini tanımlamaktadır. Yığın-fabrikası ismi, yeni yığın nesneleri oluşturan bir nesneyi tanımlar. (Push: İtki)

(yeni yığın-fabrikası) Burada s olarak tanımlanan yeni, boş bir yığını döndürür.

(Push s 3) s’yi değiştirir (3 ile genişletir).

(Push s 4) s’yi değiştirir (4 ile genişletir).

(Pop s) s’yi değiştirir (4’ü kaldırır). 4 döndürür.

(Pop s) s değiştirir (3’ü kaldırır). 3 döndürür.

(Pop s) Boş döndürür, istisna durumudur.

Aşağıdaki örnekler, arayüzleri göstermektedir. Asapların Bir arayüz, bir nesneye uygulanabilen bir dizi isteği tanımlar. Her arabirim, bir istek şeması kümesi olarak gösterilir; burada bir istek şeması, belirli bir işlemi belirten muhtemel taleplerin listesini tanımlayan bir kalıptır. Bir istek şemasında bulunan • sembolü, bir bir arayüzü karşılayan nesnenin, meşru bir şekilde ortaya çıkabileceği bir öz nitelik konumunu ifade eder. Yığın arayüzünde, bir yığın nesnesinin ortaya çıkabileceği bir öz nitelik belirmektedir. Diğer öz nitelikler, türler kullanılarak açıklanmıştır. (Bu durumda, tamsayı)

Yığın arayüzü, bir yığın nesnesini karakterize eden hizmetleri açıklar:

(Push • Tamsayı) Sonuç yok.
(Pop • ) Bir tam sayı veya boş değer döndürür, bir istisnadır.

Kuyruk arayüzü, bir kuyruk nesnesini karakterize eden hizmetleri açıklar:

(Push • Tamsayı) Sonuç yok.
(Pull • ) Bir tam sayı veya boş değer döndürür, bir istisnadır.

Havuz (Sink) arayüzü, yığınlar ve kuyruklar için ortak olan hizmetleri açıklar:

(Push • Tamsayı) Sonuç yok. (ortak metod, işlev, fonksiyon)

Aşağıdaki şekil, bu üç arabirim arasındaki uygunluk ilişkilerine dayanan bir arabirim hiyerarşisini göstermektedir:


Yürütme esnasında çalışan benzer bir mekanizmaya Delegasyon adı verilir: Bir nesne, bir isteği diğer nesnelere delege edebilir, ve bu isteğin ardından, asıl talep edilen hizmeti kendisi adına (uygun kısımlarını) yerine getirir. (Delege edilmiş bir talep özel bir taleptir çünkü asıl talep hakkında, sonraki hizmet sağlayıcısının, asıl talebin öz niteliklerini kullanarak başka talepler oluşturmasını sağlayacak şekilde, bilgi taşımaktadır.)

Yarar: Yukarıda listelenen bakım ve boyut avantajlarına ek olarak, uygulanımların kısmı paylaşımı, yazılım yeniden kullanımının faydalarını, gereksinimlerin benzer fakat aynı olmayan durumlara kadar genişletir. Kısmi uygulanımların ortak kullanımı, ilgili nesneler arasında tutarlı davranışı teşvik etmek için yararlı bir tekniktir.

Örnek: Smalltalk ve C++’da, bir sınıf, varolan bir sınıftan (üst sınıf veya temel sınıftan) miras alınarak (türetilerek) tanımlanabilir. Yeni sınıf varolan sınıfın tanımını veri bildirimleri ekleyerek (örnek değişlenleri veya veri üyeleri) ve yeni işlemler uygulayan işlemler (metodlar ya da üye fonksiyonlar) tanımlayarak genişletebilir. Yeni sınıf, varolan sınıfın tanımını ayrı ayrı metodları veya üye fonksiyonları değiştirerek ya da iyileştirerek varolan sınıfın tanımını rafine hale getirebilir. Bir sınıf, miras alma kullanılarak değişimi destekleyecek şekilde tasarlanabilir: Sınıf, belli başlı metodları miras alarak, değiştirerek veya iyileştirerek özelleştirilebilir. Örneğin grafik nesneleri için ortak davranışı tanımlayan genel grafik nesnesi sınıfı, “resim çiz” (draw) metodunun belirli bir grafik nesnesi tanımlayan her miras alan sınıfta değiştirilmesi beklentisiyle tasarlanabilir.

3 Terminoloji

Bu bölümde, yukarıda tanıtılan temel kavramlar ve bizim tecrübemize göre iletişim sorunlarına neden olabilecek ek konular için terimler tanımlamaktayız. Terimleri belirli alanlardaki, (nesne-yönelimli programlama gibi), ya da belirli sistemlerdeki (C++ programlama dili gibi) ortak kullanımlarına göre birbirleriyle ilişkilendirmekteyiz. Terimler eşanlamlılarının seçimi ve mevcut kullanımdaki ilişkili terimleri ile birlikte ekteki tabloda gösterilmişlerdir. Tanımlar üç bölüme ayrılmıştır: soyutlama ile ilgili terimler, talep eden hizmetlerle ilgili terimler ve hizmet sunumuyla ilgili terimler.

3.1 Soyutlama ile ilgili terimler

Nesne

Tanım: Bir nesne, istemciler (kişiler veya programlar) tarafından talep edilen hizmetleri sunmakta görünür rol oynayan varlıktır. Bir nesne açıkça belirli taleplerin davranışı ile karakterize edilen soyutlamanın vücut bulmuş halidir. Hizmetler, nesnelerle ilişkili verilere erişebilir veya bunları değiştirebilir. Hizmetler, verilerin biçimine veya hizmetleri uygulanımı için kullanılan algoritmalara bağımlı olmadan tanımlanmaktadır; Özellikle, aynı davranışın birkaç muhtemel uygulanımı olabilir. Tanımlanan bir hizmete, işlem (operation) adı verilir.

Önerilen Terimler ve mevcut kullanımla ilgili olan terimler

Nesne: Örnek, sınıf örneği, vekil, varlık

Kapsüllenmiş nesne: Bilgi gizleme

Gömülü nesne: Kapsüllenmiş araç, vekil (proxy), dış metod, entegre uygulama

Korumalı nesne: Erişim kontrolü

Nesne referansı: olanak, tanıtıcısı, nesne referansı, nesne adı

Talep (istek): mesaj, metod çağırma, fonksiyon çağırma

Genel (jenerik) işlem: mesaj seçici, metod, genel (jenerik) fonksiyon, aşırı yüklü fonksiyon, sanal üye fonksiyonu, polimorfizm, dinamik bağlama Arayüz: Protokol, tür, soyut sınıf, sanal sınıf, imza

Arayüz hiyerarşisi: Kalıtım (Miras alma), özellik hiyerarşisi, tür hiyerarşisi, sınıf hiyerarşisi, alt-türleme, uyumluluk

Tür: sınıf

Alt sınıf: alt sınıf, türetilmiş sınıf

Dinamik bağlama: geç bağlama

Statik bağlama: erken bağlama

Nesne uygulanımı: sınıf, tür, şablon, yönetici, sunucu

Durum değişkeni: Örnek değişkeni, veri üyesi, öz nitelik, alan, oluk (slot)

Yöntem: Üye foksiyon

Uygulanım mirası: alt-sınıflama (sub-classing), türev, ön ek alma

Örnek: Nesnenin basit bir örneği push ve pop işlemleriyle davranışı karakterize edilen, yığın (stack) veri yapısıdır. Bu işlemler, altta yatan veri gösterimine (ki dizi veya bağlantılı liste olabilir) referans verilmeden, doğrudan tanımlanmakta ve kullanılmaktadırlar. Push ve pop işlemleri için gereken kod parçaları, soyut yığın yapısının parçası olmayan, array-index veya list-head gibi gizli (private) işlemler aracılığıyla altta yatan veriye erişirler.

Eş Anlamlılar ve İlgili Terimler: Nesnelere bazen sınıf örnekleri adı verilir. Bazı zamanlarda nesnenin, başka birşeyi modellediğini ifade etmek için suret (vekil, surrogate) terimi de kullanılmaktadır.

Kapsüllenmiş nesne

Tanım: Sadece istemciler tarafından talep bildirildiğinde erişilebilen nesne türüne kapsüllenmiş nesne adı verilir.

Örnek: C++ gibi, nesne yönelimli bir programlama dilinde, nesnenin uygulanımı için kullanılan veri yapıları ve ilgili işlemler, nesneye istekte bulunan istemcilerden gizlenmişlerdir. Örneğin, bağlantılı liste kullanılarak yazılmış bir yığına, istemciler bağlantılı liste işlemleri kullanarak erişemezler.

Eş anlamlılar ve İlgili Terimler: Kapsülleme, aynı zamanda bilgi gizleme olarak da adlandırılmaktadır. Kapsülleme terimi bazen, nesnenin bağımsız, yani diğer nesnelerle bilgi paylaşmadığını ve fiziksel olarak tek bir yerde temsil ettiğini vurgulamak için kullanılır.

Gerekçe: Bu kavram, kapsülleme teriminin üç ortak anlamından biridir. Bu tanımın amacı, tercih edilen kullanımı belirtmektir. Sonraki iki tanım, diğer anlamlar için alternatif terimler sunar.

Gömülü nesne

Tanım: Gömülü nesne, hali hazırda var olan bir yapı veya işlemin (örneğin nesne olmayan) nesne yapısına sarıldığı, uygun bir arayüz kodu ile yaratılan nesnedir.

Örnek: Uç birim (terminal) için yazılmış bir uygulama, kullanıcı arayüzü tarafından üretilen istekleri, kullanıcı tarafından girilen karakterleri, çıktı karakterleri olarak uygun sunum nesnelerine çevirerek nesne-yönelimli kullanıcı arayüzü standartlarına uyması için üretilmiştir.

Eş Anlamlılar ve İlgili Terimler: Gömülü nesneler oluşturmaya, genellikle kapsülleme veya araç kapsülleme adı verilmektedir. Kapsülleme teriminin bu kullanımı, kapsüllenmiş nesne ifadesinden farklıdır. Uygulama entegrasyonu ve Araç entegrasyonu terimleri ilgili terimlere dahillerdir. Ağ yönetiminde kullanılan gömülü nesnelere vekil (proxy) adı verilir.

Gerekçe: Bu kavram, kapsülleme teriminin yaygın olarak kullanıldığı üç kavramdan biridir. Gömme terimi, bu kavramı, kapsüllenmiş nesnelerden ayırt edebilmek için alternatif olarak seçilmiştir.

Belirsiz Terimler

Terminolojiyi geliştirirken hatalı iletişim ve kafa karışıklığı yaratan bazı terimlerle karşılaştık.

Kapsülleme, en çok kafa karışıklığı yaratan terimdir. Var olan kullanımda, kapsülleme teriminin üç farklı anlamı var: Soyutlama için engeller koymak (çn. bilgi gizleme), yabancı bileşenlerin sisteme entegre edilmesi (çn. gevşek veya sıkı bağlılık), farklı kullanıcıların hizmetlere olan erişimlerinin denetlenmesi. (çn. erişim kontrolü) Bu kavramlar için, sırasıyla kapsülleme, gömme ve koruma terimleri önerilmiştir.

Miras terimi de kafa karışıklığına sebep olmaktadır. Mevcut kullanımda mirasın iki temel anlamı vardır: Nesnelerin uygulanımlarının tanımlamalarının paylaşılarak organize edilmesi ve ortak davranış ve arayüzler vasıtasıyla nesnelerin sınıflandırılması. (Bu kavramlar için sırasıyla önerilen kavramlar, uygulanım kalıtımı ve arayüz hiyerarşisidir)

Diğer kafa karıştırıcı iki terim de tür ve sınıf terimleridir. Bu terimler, aynı anda nesnelerin dış arayüzleri veya nesnelerin uygulanımı anlamlarına gelebilmektedirler.

Birden çok anlama gelen şeylerin ayrımını yapmak, temel kavramlara aşina olan kişiler için dahi ince bir ustalık gerektirebilmektedir.

Korumalı Nesne

Tanım: Korumalı nesne, belirli istemcilerin kendine olan hizmet taleplerini kısıtlama yeteneğine sahip olan nesnedir.

Örnek: Bir posta kutusu (mailbox) nesnesi, yalnızca belirli bir kişinin read (okuma) isteğine cevap verir.

Eş anlamlılar ve İlgili Terimler: Korumalı nesnelerin erişim kontrolü sağladığı söylenir.

Gerekçe: Bu kavram sıklıkla kapsüllenmiş nesne kavramı ile karıştırılmaktadır. Aslında, bazı sistemler kapsülleme ve koruma için benzer mekanizmalar kullanmaktadırlar. (Korumalı nesnelerin aynı zamanda kapsüllenmiş olmaları da beklenebilir.) Korumalı terimi, işletim sistemleri alanındaki ortak kullanıma dayanarak seçilmiştir.

3.2 Hizmet talep etme ile ilgili terimler

Nesne referansı

Tanım: Nesne referansı, belirli bir nesneyi, güvenilir bir şekilde tanımlayan bir değerdir.

Örnek: C++’da, bir işaretçi değeri, bir nesne referansı görevi yapar. HP NewWave ortamında, bir belge nesnesinden bir grafik nesnesine yapılan bir bağlantı, bir nesne referansıdır.

Unix dosya sisteminde, dosya adı bir referans değildir, çünkü zamanla dosyanın veya içinde bulunduğu dizinin adı değişebilir.

Eş Anlamlılar ve İlgili Terimler: Nesne referansı, bazen tanıtıcı (handle), nesne tanımlayıcısı (object identifier) veya nesne ismi (object name) olarak da adlandırılabilmektedir.

İstek

Tanım: Bir istek, bir hizmetin gerçekleştirilmesi için, bir istemci tarafından gerçekleştirilen eylemdir. Bir istek, istenen hizmeti belirten bir işlemi tanımlar. Bir istek, nesneleri tanımlamak için gerekli olan öz nitelikleri içerir. Bir istek, hizmetin nasıl yapılacağını tek başına belirlemez.

Bir istek bildirildiğinde, bir bağlama (binding) işlemi gerçekte yürütülecek kodu ve kod tarafından erişilecek verileri belirler. Bir isteği yerine getirmenin sonucu, sonuçları istemciye döndürmek olabilir; Sonuçlar istenen hizmet yerine getirilirken, ortaya çıkan olağan dışı durumları içeren durum bilgisi benzeri değerleri de içerebilir.

Örnek: Nesne-yönelimli programlama dilinde,programlama diline özgü bir çağrı biçiminin çalıştırılmasıyla, istek bildirilmiş olur. Nesne yönelimli bir kullanıcı arayüzünde, istekler, farenin belli bir görsel imgenin üzerinde gezinirken, farenin butonuna tıklanmasına benzer, fare hareketleri aracılığıyla bildirilmektedir.

Eş Anlamlılar ve İlişkili Terimler: Smalltalk’da, bir istekte bulunmaya, mesaj gönderme veya mesaj devretme denir. C++’da, bir istek bildirme, üye fonksiyonun çağrılması (member function invocation) olarak adlandırılır. CLOS’da, bir istek yayınlamak jenerik fonksiyon (işlev) çağrısı olarak adlandırılır.

Gerekçe: İki nedenden dolayı, geleneksel “mesaj” terimini kullanmaktan kaçınmaktayız. Birincisi, mesaj göndermenin istemci ve hizmet sağlayıcı tarafından eş-zamanlı yürütülmesi anlamına geldiği yanlış anlaması yaygındır.

Diğeri, bir mesajın işlem yapıldığı tek bir konuma gönderildiği yanlış anlamasıdır. Klasik ve genelleştirilmiş nesne modellerinde tanımlandığı üzere, bu tanım genelleştirilmiş nesne modelleri için hatalı olabilir.

Jenerik (Genel) İşlem

Tanım: Jenerik (genel) bir işlem, farklı nesneler için, gözle görülür şekilde farklı davranışlar gösteren, istemciler tarafından keyfi olarak talep edilebilen ve farklı uygulanımları olan bir işlemdir türüdür.

Örnek: Yazdırma işlemi, yazdırılabilir herhangi bir nesneden talep edilebilir, örn. bir doküman

veya bir elektronik tablo.

Eş anlamlılar ve İlgili Terimler: C++’da, jenerik işlemlere, sanal üye (virtual member functions) fonksiyonlar adı verilir. Smalltalk’ta ise aynı kavrama mesaj seçici (message selector) denir. Jenerik İşlem yeteneği, aynı zamanda polimorfizm (çok biçimlilik) ve fonksiyon aşırı yükleme olarak adlandırılmaktadır. (Bakınız statik ve dinamik bağlama.)

Gerekçe: Jenerik kelimesi, hizmetin birçok nesne için ortak olduğu gerçeğini vurgular.

Arayüz

Tanım: Bir arayüz, bir nesnenin olası kullanım biçimlerinin tanımıdır. Özellikle, bir arayüz, nesneyi bir öz nitelik olarak tanımlayan bir dizi muhtemel istek anlamına gelir. Bir arayüz tarafından tanımlanan olası kullanımlar anlamlılar ise, “nesne arayüzü sağlamaktadır” denir. Bir arayüz, öz niteliklerin ve dönen sonuçların tür ve isteklerin davranış tanımlarını yapabilir. Bir nesnenin temel arayüzü (principal interface), nesnenin olası tüm kullanımlarını açıklayan bir arayüze verilen addır.

Örnek: Bir yığın arayüzü push ve pop işlemlerinden oluşabilir. Sadece tamsayı türünden verilerin yığına push işlemi aracılığıyla eklenmesine olanak veriyor olabilir. (Bakınız: Yığın örnek işlemleri)

Eş anlamlılar ve İlgili Terimler: Protokol terimi, sıklıkla, nesnelere gönderilmesi mümkün bir mesaj kümesini tanımlamak için kullanılır. Öz nitelik ve sonuç türlerini tanımlayan bir arayüze imza (signature) denir.

Birçok nesne yönelimli programlama dilinde, bir arayüz, soyut sınıf veya sanal sınıf tarafından tanımlanır ve bu sınıf uygulanım-tabanlı bilgiyi (ör. Işlev kısımları — procedure bodies ) önemsemez ve doğrudan uygulanımları mümkün değildir. Tür olarak kullanılan bir arayüze, arayüz-tür (interface type) denir.

Arayüz Hiyerarşisi

Tanım: Arayüz hiyerarşisi, arayüzlerin ve dolayısıyla nesnelerin arayüz uygunluğu (object-conformance) terimlerine göre sınıflandırılmasıdır. Bir arayüz, eğer birinci arayüze uygun olan nesne, mutlaka ikinci arayüze de uygun ise, diğer arayüze uygundur.

Örnek: Kuyruk ve yığın veri yapılarının ikisi de, tek bir verinin tek bir seferde eklenebildiği veri havuzları olarak düşünülürler. Yığın arayüzü push ve pop isteklerinden oluşur. Kuyruk arayüzü ise, push ve pull steklerinden oluşur. Bu iki yapının paylaştığı hizmet havuz (sink) arayüzüdür ki, sadece push isteğinden oluşur. Yığın ve kuyruk arayüzlerinin her ikisi de havuz arayüzünü sağlamaktadır. Havuz arayüzünü sağladığı varsayılan nesnelerle çalışan (yani nesnelere sadece push isteği gönderen) bir program, yığın ve kuyruk nesneleriyle çalışabilir. (Yığın ve kuyruk örneklerine bakınız.)

Eş Anlamlılar ve İlgili Terimler: Arayüz hiyerarşilerine, belirtim hiyerarşileri de denir. Arayüz uygunluğunun bir kalıtım mekanizması kullanılarak tanımlandığı sistemlerde, arayüz hiyerarşisine bazen kalıtım hiyerarşisi denir; bununla birlikte, bu kavram için kalıtım (miras) terimini kullanılmasını önermiyoruz. (aşağıda uygulanım mirasına bakınız). Arayüzlerin tür olarak kullanıldığı sistemlerde, arayüz hiyerarşisine, tür hiyerarşisi veya alt-tür hiyerarşisi denilebilir. C++ gibi, arayüzlerin, uygulanımlarından ayrılmadığı sistemlerde, arayüz hiyerarşisine, sınıf hiyerarşisi de denilebilir.

Gerekçe: Kalıtım (miras) teriminin birçok kullanımından biri, arayüz hiyerarşisine gönderme yapmaktadır. Kalıtım kelimesini, özellikle arayüz uygulanımında sınıflandırma termininden ayırmak için, birikimli bir tanımlama mekanizması anlamına gelmesi için kısıtlamayı seçtik.

Arayüz kalıtımı terimi, nesnelerin, istemciler tarafından görülebilen davranışlarına (hizmetlerine) göre sınıflandırılmasını vurgulamaktadır. Arayüz uygunluğuna dayalı sınıflandırma, katı bir hiyerarşi oluşturmamalıdır; Bununla birlikte, hiyerarşi terimi, kafes (lattice) gibi diğer daha teknik terimlere nazaran daha yaygın olarak kullanılması ve anlaşılması avantajına sahiptir.

Tür

Tanım: Tür, anlamlı kullanımları karakterize eden değerlerin sınıflandırılmasıdır. Özellikle, bir tür, türe uyan değer kümesini tanımlayan bir beyan anlamına gelir (türün uzantısı olarak adlandırılır). Her nesne sistemi kendi anlamlı kullanım ve tür eğilimin tanımlamaktadır. Türlere sahip olan nesne yönelimli bir sistemde, öz niteliklerin ve isteklerin sonuçlarının belli sınırlar içerisinde olması, türler tarafından karakterize edilmektedir.

Örnek: Türlere sahip olan nesne-yönelimli programlama dili, değişkenleri için tür tanımlamaları sunmaktadır. Bir değişken, sadece beyan edilen türü sağlayan değerleri ifade edebilir. Nesne türleri, örneğin arayüz terimleri kullanılarak (yazdır işlemini destekleyen tüm nesneler) veya uygulanım terimleri (stack-as-list yani liste-bazlı-yığın uygulanımına sahip olan nesnelerin türü), gibi farklı şekillerde ifade edilebilir. Türlere sahip birçok nesne-yönelimli programlama dilinde, arayüz ve uygulanım türlerini tanımlamak için tek bir sınıf yapısı kullanılmaktadır.

Eş anlamlılar ve İlgili Terimler: Sınıf terimi genellikle tür yerine, özellikle nesne uygulanımlarının tür kavramının tek gösterimi olduğu Smalltalk gibi sistemlerde kullanılır.

Alt-tür

Tanım: Bir türün (üst-sınıf) alt-türü, alt-türün koşullarını sağlayan her değerin, üst-türün koşullarını da mutlaka sağladığı türdür. Arayüzlerin tür kavramına tekabül ettiği sistemlerde, arayüz uygunluğu (interface conformance) bir alt-tür ilişkisine örnektir.

Örnek: Çalışan kavramı, kişi kavramının alt türüdür: her çalışan nesnesi, aynı zamanda kişi nesnesidir. Jenerik bir işlem, belirli bir türden nesnelerine uygulanması için tanımlanır. Bu işlem, aynı zamanda, belirli bir türün alt-türlerine de uygulanabilir.

Eş anlamlılar ve İlgili Terimler: Uygulanım kalıtımının alt-tür yaratmanın tek yolu olduğu sistemlerde, alt-tür, alt-sınıf veya türemiş sınıf olarak adlandırılmaktadır.

Dinamik Bağlama

Tanım: Dinamik bağlama, istenen bir hizmeti gerçekleştirmek için talep bildirildiği anda yapılan kod seçimidir.

Örnek: Smalltalk’da her istek hedef nesne için uygun olan metodu bulmak için, sınıf hiyerarşisi incelenerek işlenmektedir. Sınıf hiyerarşisinde metod eklemek ya da yeniden tanımlamak gibi yapılacak her değişiklik, devam eden istekler için anında etkinlik kazanır.

Eş Anlamlılar ve İlgili Terimler: Dinamik bağlama aynı zamanda geç bağlama olarak da adlandırılır.

Statik Bağlama

Tanım: Statik bağlama, istenen bir hizmeti gerçekleştirmek için kullanılan kod seçiminin önceden yapılmış olması durumudur. Statik bağlamayı destekleyen sistemler, azaltılmış genelleme ve genişletilebilirlikten ödün vererek, daha iyi performans ve iyileştirilmiş hata denetimi sınarlar.

Örnek: C ++’da, işaretçi veya referans olmayan bir değişken, belirli bir sınıfa ait (o sınıftan türemiş olmayan) bir nesneyi ifade etmesiyle tanınır; bu değişken üzerindeki bir sanal üye fonksiyonunun çağrılması, belirli bir prosedür üzerinde doğrudan bir çağrı olarak derlenebilir.

Eş Anlamlılar ve İlgili Terimler: Statik bağlama, erken bağlama olarak da adlandırılır.

3.3 Hizmet sunumuyla ilgili terimler

Nesnenin Uygulanımı

Tanım: Bir nesne uygulaması, bir nesneyle ilişkili hizmet kümesinin nasıl yürütüleceğinin yürütülebilir bir açıklamasıdır. Nesne ile ilişkili verilerin biçimini ve hizmetlerin veriyi nasıl değiştirdiğini tanımlamaktadır. Birden fazla nesne ortak bir uygulanımın parçalarını paylaşabilir; yürütülebilir kod nesneler arasında paylaşılsa da, her nesne tipik olarak verilerin kendi kopyasına sahiptir.

Örnek: Bir daire nesnesi, dairenin durumunu iki durum değişkeni ile tanımlıyor olabilir: Merkez ve çap. Ayrıca daire nesnesi genişle ve yer değiştir adında iki metoda da sahip olabilir.

genişle(çarpan) çap := çap*çarpan;

yer değiştir (yer değiştirme miktarı) := merkez + yer değiştirme miktarı;

Eş Anlamlılar ve İlgili Terimler: Bir nesne uygulanımı tarafından verilen veri biçimi bazen şablon olarak adlandırılır. Birden fazla nesnenin uygulanımına bazen yönetici veya sunucu denir. Bir sınıf, ortak bir uygulanımı paylaşan birden fazla nesne oluşturmak için örneklendirilebilen bir nesne uygulanımıdır; Nesneler sınıfın örnekleri olarak adlandırılır. Bir Fabrika, nesneler yaratmak için hizmet sağlayan bir nesnedir; Bu nedenle sınıf nesnesi de bir fabrikadır.

Durum Değişkeni

Tanım: Durum değişkeni, nesnelerle ilişkili verilerin somut gerçekleşimi olarak görev yapan bir değişkendir. Bir durum değişkeni, tek bir nesneyle veya birden çok nesneyle ilişkilendirilebilir. Durum değişkenleri, nesne uygulamalarında sıklıkla bu durum değişkenlerini okuyabilen ve yazabilen yöntemlerle tanımlanır.

Eş Anlamlılar ve İlgili Terimler: Durum değişkenleri aynı zamanda örnek değişkenleri, veri üyeleri, alanlar, özellikler veya oluklar (slots) olarak da adlandırılır

Gerekçe: Bir durum değişkeni, zamana bağlı olarak değişen davranışın uygulanımını gerçekleştiren bir araç olduğunu, nesnelerin istemci tarafından görülebilen davranışına karşıt olarak vurgular. Örnek değişkeni terimi, örneklendirilemeyen olmayan nesneler için uygun değildir.

Metod

Tanım: Metod, hizmetleri gerçekleştiren bir işlemdir. Tipik olarak, bir nesnenin desteklediği her işlem için bir metodu (yöntemi) vardır. Metodlar, nesne uygulanımlarında, sıklıkla okumakta ve yazmakta oldukları durum değişkenleriyle birlikte tanımlanmaktadır.

Eş anlamlılar ve İlgili Terimler: C ++’da, metodlara üye fonksiyon tanımları denir.

Uygulanım kalıtımı

Tanım: Uygulanım kalıtımı (kolaylık sağlamak için burada sadece kalıtım denmiştir), nesne uygulamalarını aşamalı olarak oluşturmak için varolan bir mekanizmadır: bir nesne, diğer nesnelerin uygulanımlarına bağlı olarak tanımlanmaktadır. Yeni uygulanım, varolan nesneleri, nesne gösterimine (veri biçimi) veri ekleyerek, yeni işlemler ekleyerek ve var olan işlemlerin tanımlarını değiştirerek veya genişleterek genişletebilir.

Nesnenin Diğer Tanımları

Diğer yazarlar, nesne yönelimli programlama dillerinin temel kavramlarını belirlemeye çalışmaktadırlar:

  • Sterik ve Bobrow, bir nesneyi, hesaplama yapan ve durum kaydeden bir varlık olarak tanımlarlar. Nesne-yönelimli programlama dillerindeki çeşitliliği kabul etmekle beraber, iki kavramı temel kavramlar olarak tanımlamaktadırlar: mesaj gönderimi (jenerik işlem talepleri) ve uzmanlaşma (uygulanım kalıtımı) ve ortak olarak sınıflara sahip olma. (örneklendirilebilen uygulanıma sahip nesneler) Mesaj gönderme, soyutlamanın açık doğasından bahsetmeseler de, veri soyutlamayı desteklemek olarak tanımlanır ve kapsüllemeye sadece kısaca değinilir. Nesne davranışı protokoller (arayüzler) açısından tanımlanmıştır, ancak arayüz uygunluğu açıklanmamaktadır. Nesne kimliklendirme açıkça ele alınmamıştır. Stefik ve Bobrow, metod özelleşmesinde ve birleşiminden, bileşik nesnelerden, perspektiflerden, ek açıklamalardan, aktif değerlerden ve meta-sınıflardan da bahsetmektedirler.
  • Wegner, nesne yönelimli veri soyutlama dilini, nesneleri (yerel bir durumu paylaşan bir işlem kümesi), sınıfları (bir veya daha fazla arayüzü tanımlayan bir örneklenebilir uygulanımı), sınıf kalıtımını ve bilgi gizlemeyi (kapsülleme) desteklemek olarak tanımlar. Jenerik işlemler kavramı, soyutlamanın apaçık doğası, nesne kimliklendirme ve arayüz uygunluğu ve sınıf kalıtımı arasındaki ayrım atlanmıştır. (Alt türleme, tür olan sınıf bağlamında açıklanmaktadır.) Wegner aynı zamanda, kesin türlendirmeden, eş zamanlılıktan, dağıtımdan ve kalıcılıktan nesne-yönelimli programlama dillerini ayrıt eden özellikler olarak bahsetmektedir..
  • Thomas, nesne yöneliminin dört anahtar kavramını şöyle tanımlamaktadır: kapsülleme, mesaj gönderme (genel işlemler için istekler), sınıf kalıtımı ve bağlama (statik ve dinamik). Nesneleri, gerçek dünyadaki varlıkların, kendini açıklayan (apaçık soyutlama) benzeşenleri (analog) olarak tanımlar. Sınıfları (örnek üretilebilen uygulanımları) ve mantıksal bir sınıf hiyerarşini açıklar; (tıpkı bir arayüz hiyerarşisinin arayüzü ile ilgili olması gibi) sınıfları dış davranışa bağlı olarak ilişkilendirir. Arayüzlerden bahsetmez. Sınıflar türlerle tanımlanır ve alt türleme, davranış koruyan sınıfı kalıtımı (uygulanım kalıtımı) olarak tanımlanır. Nesnenin kimliklendirilmesi ele alınmamıştır. Thomas ayrıca meta-sınıflardan, bileşik nesnelerden ve özel mesajlardan (erişim denetiminin bir biçimi olarak) bahseder.
  • Wand, nesnelerin mantıklı durumlarını ve durum dönüşümlerini sınırlandıran bir yasaya bağlı olarak, hizmetler ve istekler kavramlarının, genel bir nesne etkileşimi kavramı ile değiştirildiği resmi bir nesne modeli sunmaktadır. Wand’ın görüşüne göre, istekler ve işlemler nesne etkileşimlerinin uygulanımıdır. Wand’ın modeli nesne yaratımını da atlamaktadır.

Bizim nesne tanımımız varolan tanımlamaların çoğundan şu şekilde farklıdır: Bir nesnenin duruma sahip olmasını gerekli olduğunu düşünmüyoruz. Her hesaplama varlığının bir nesne olmasını gerektiğini düşünmüyoruz. Bize göre, tek tek nesnelerle ilişkili olmayan veya birden çok nesneyle paylaşılan durum mümkündür. İsteklerin birden çok nesneyi içermesine ve üçüncü taraflar tarafından gerçekleştirilmesine izin veriyoruz. Bu genellemeler daha geniş bir nesne sistemi yelpazesini belirlemek içindir. Ayrıca, bizim tanımımız nesne kimliklendirmeyi, jenerik işlem kavramını ve hizmetler ve uygulanımlar arasındaki ayrımı (arayüzler) ve arayüz hiyerarşisi (sınıflandırma) ile uygulanım mirası (yapım) arasındaki ayrımı vurgulamaktadır. Belki de en önemlisi, yalnızca programlama dilleri için değil, birçok alana uygun terim ve tanımları kullanmaya çalışıyoruz.

Tekli kalıtım, bir nesne uygulanımının, tek bir varolan nesne uygulanımı açısından tanımlanmasına izin verir. Çoklu kalıtım, yeni bir nesnenin tanımlanmasında birden fazla nesne uygulanımı kullanılmasına izin verir. Kalıtım, genellikle bir sınıfın diğer sınıflardan miras aldığı sınıfsal kalıtımı biçimini alır.

Kalıtım, bir nesnenin veya sınıfın metinsel tanımını kopyalayarak ve düzenleyerek, yeni bir tanım üretmek için etkilidir; ancak eski tanımdaki değişiklikler (sonuç olarak) yeni tanıma yayılır. Ayrıca kalıtım, nesne uygulanımlarını bir kalıtım hiyerarşisinde organize etmenin bir yolunu sunmaktadır.

Örnek: Başlıklı Pencere gibi bir isme sahip olan bir sınıf, pencere sınıfından miras alınacak şekilde tanımlanabilir. Başlıklı pencere sınıfı, bir başlık örnek değişkeni ve başlık ile ilgili işlemlerin (başlığı döndürmek için, başlık işlevi) (başlığı düzenlemek için başlık-düzenle işlevi) uygulanımını sağlayan prosedürleri tanıma ekleyecektir.

Eş anlamlılar ve İlgili Terimler: Kalıtımı, birikimli tanımlama için herhangi bir mekanizma olarak tanımlamaktayız. Kalıtım ile tanımlanan bir sınıf, tanımlanmasında kullanılan sınıfların alt sınıfı olarak adlandırılır ve buna üst sınıflar denir. C++’da, alt sınıf, türetilmiş sınıf olarak da adlandırılır ve bir üst sınıf, taban sınıf olarak adlandırılır. Bir devralma hiyerarşisine, uygulanım hiyerarşisi veya sınıf hiyerarşisi de denir.

Gerekçe: Kalıtım, birçok türde hiyerarşiye göndermede kullanılan yaygın bir terimdir. Nesne yönelimli sistemlerde öncelikle arayüz hiyerarşilerine ve birikimli tanım mekanizmalarına değinmek için kullanılır. Kalıtım terimini, bir ilişkiden ziyade, kalıtım kelimesinin günlük kullanımına uygun olarak, bir işlemi belirtmek için kullanılan ikinci kavram (çn. birikimli artım mekanizması) olarak sınırlamaktayız.

4 Teşekkürler

HP object task force grubunun üyelerine bu çabaya olan katkılarından ve Walter Olthoffand ve Walt Hill’in yardımlarından dolayı teşekkür ediyoruz. Ayrıca, Hewlett-Packard çalışanlarına ve önceki belgeleri inceleyen ve önerilerinde iyileştirmeler sağlayan Nesne Yönetimi Grubu teknik komitesinin üyelerine de minnettarız. Katkılarından ötürü Bill Kent’e özellikle minnettarız.

5 Referanslar

1. D. G. Bobrow, L. G. DeMichel, R. P. Gabriel, S. E. Keene, G. Kiczales, D. A. Moon. Common Lisp Object System Specification X3J13. SIGPLANNotices 23, 9 (1988).
2. I. J. Fuller, et al. An Overview of the HP NewWave Environment. HP Journal 40, 4 (Aug. 1989), 6–23.
3. J. Johnson, et al. The Xerox Star: A Retrospective. Computer 22, 9 (Sept. 1989), 11–29.
4. M. R. Cagan. The HP SoftBench Environment: An Architeeture for a New Generation ofSoftware Tools. HP Journal 41, 3 (June 1990), 36–47.
5. D. H. Fishman, et al. Iris: An Object-Oriented Data Base System. ACM Transactions on Office Information Systems 5, 1 (1987), 48–69.
6. S. McKay, W. York, and M. McMahon. A Presentation Manager Based on Application Semantics. Proc. ACM Symposium on User Interface Software and Technology, Nov. 1989, 141–148.
7. ISO. Information Technology -Open Systems Interconnection -ManagementInformation Services -Structure ofManagement Information -Part 1: Management Information Model. Draft International Standard 10165–1. ISOIIEC JTCl/SC21 N5252, June 1990.
8. R. M. Soley, ed. Object Management Architecture Guide. Object Management Group, Inc. Framingham, Ma., October 1990.
9. P. Wegner. Learning the Language. Byte, March 1989,245–253.
10. D. Thomas. What’s in an Object? Byte, March 1989, 231–240.
11. M. Stefik & D. G. Bobrow. Object-Oriented Programming: Themes and Variations. AIMagazine 6, 4 (Winter 1986), 40–62.
12. Y. Wand. A Proposal for a Formal Model of Objects. In Object-Oriented Concepts, Databases, and Applications. W. Kim, F. H. Lochovsky, eds. ACM Press, 1989, 537–559.


Projelerle PHP 7

Ben Mutlu Koçak, Bilgisayar Mühendisiyim, ZCPE Sertifikasına sahibim ve “Hiç Bilmeyenler İçin İnternet Programlamaya Giriş — PHP 7” adlı kitabın yazarıyım. Kitabım: https://www.seckin.com.tr/kitap/911934237
Özgeçmişim:
http://represent.io/mtkocak.pdf 
Websitem:
http://mynameismidori.com