Java Günlüğüm
Yazılım, Java, BT, azıcık felsefe, biraz mizah...
  • Udemy Eğitimleri
  • Temiz Kod
  • Tasarım Kalıpları
  • Hakkımda
  • Arşiv
RSS
15 Şubat 2015

Tasarım Kalıpları: Singleton (Tek Nesne) – IV – Değerlendirme

Akin Java, Tasarım Kalıpları, Yazılım Modelleme

Şu ana kadar Singleton tasarım kalıbının mekanizmaları üzerinde durduk. Bu yazıda Singleton kalıbının kullanımları üzerine bir değerlendirme yapalım.

Singletonı bir kalıp yerine ters-kalıp (anti-pattern) görme eğilimi vardır. Bunun en temel sebebi ise tek olan nesnenin, erişim kolaylığından dolayı global bir değişkene dönüşebilmesidir.

Global değişkenler, görünürlük alanları açısından (scope) herhangi bir kısıtlamaya sahip olmayan, dolayısıyla yazılımın her yerinden erişen değişkenlerdir. Bu yüzden global değişkenler, yazılımın farklı soyutlamaları arasındaki ortak olarak kullanılırlar. Bu durum ise yazılımın farklı parçalarının birbirlerine daha bağımlı olmasına sebep olur. Öte yandan ortak yapılar, yazılımdaki soyutlamaların odaklanmasını da engelleyici mahiyettedir. Bu yüzden örneğin ben, özellikle C gibi global değişkenlere izin veren dillerin kültüründen gelen kişilerin bulunduğu eğitim ortamlarında sıklıkla “Java’da global değişken yoktur!” diye vurgularım.

Nesne-merkezli yapıların, prosedürel yapılara en temel üstünlüğü, soyutlama mekanizması olarak fonksiyon yerine nesneyi koymuş olması ve bu sayede daha yetkin yerel bir ifade yapısı elde etmiş olmasıdır. Hem ifade gücü hem de değişim yönetimi açısından nesnelerin fonksiyonlara göre çok daha yetenekli olması, fonksiyonların sağlayamadığı yerelliği, nesnelerin sağlamasından kaynaklanmaktadır. (Bu konuyu burada ve burada ele almıştık.) Bu yaklaşımda bahsettiğimiz yerellik ve globallik, sorumluluklar açısından anlamlı kavramlardır. Bu açıdan bakıldığında, nesne-merkezli programlama bir yerelleştirme, çapı küçültme, yani modülerleştirme dolayısıyla da globallikten uzaklaşma felsefesi barındırmasına rağmen, Singleton kalıbıyla bunun tam tersi yönde bir mekanizma sağlaması çelişkili bir durum olarak görülebilir.

Bu noktada Kent Beck ve Ward Cunningham’ın şu sözlerine kulak vermekte fayda vardır:

“The most difficult problem in teaching object-oriented programming is getting the learner to give up the global knowledge of control that is possible with procedural programs, and rely on the local knowledge of objects to accomplish their tasks. Novice designs are littered with regressions to global thinking: gratuitous global variables, unnecessary pointers, and inappropriate reliance on the implementation of other objects.

Because learning about objects requires such a shift in overall approach, teaching objects reduces to teaching the design of objects. We focus on design whether we are teaching basic concepts to novices or the subtleties of a complicated design to experienced object programmers.”

Singleton kalıbıyla hem durumu (state) hem de davranışı (behavior) global yapma imkanımız var. Bu ise Singleton üzerinde ciddi bir bağımlılık (coupling) oluşturmaktadır. Yani Singleton olan nesne, hem uygulamanın her tarafından erişilebilir hem de muhtemelen uygulama boyunca bellekte kalmaya devam eder. Bu durum ise, aksi halde aralarında hiç bir bağımlılık olmayacak uygulama parçalarının singleton ile ciddi bir bağımlılığa sahip olmalarına sebep olur. Dolayısıyla singleton kullanımının bizi nesne-merkezli programlamadan prosedürel programlama götürdüğü, bu yüzden ters-kalıp olduğu iddia edilmektedir.

Singleton hakkında bir başka nokta ise hakikatten Singleton nesneye ihtiyacın olup olmadığı durumdur. Yani projenizde bir noktada işin kolayına kaçarak bir nesneyi singleton yaparsanız, ileride o nesnenin Singleton olmasından kaynaklanan sıkıntılar yaşayabilirsiniz. Örneğin, performans ve ölçeklenirlik gerekliliklerinden dolayı birden fazla JVM i grup (clustered) olarak kullanmak istediğinizde ya da sisteminizde faklı sınıf yükleyiciler (class loaders) olduğunda, Singleton nesnelerinin artık gerçekten Singleton olmadığını görebilirsiniz. Ben, Singleton’un çok çekici tabiatından dolayı, pek çok şeyin çözümüymüş gibi, olur-olmadık yerlerde kullanıldığına şahit oldum. Singleton’un tasarım kalıplarını yeni öğrenmeye başlayan programcının zihnindeki durumu, “Elinde çekiç olan kişi her şeyi çivi olarak görür” atasözünü hatırlatır 🙂

Singleton2un bu kullanımlarından dolayı ters-kalıp (anti-pattern) haline gelmiş olduğunu, bizzat GoF da buradaki “Design Patterns 15 Years Later” başlıklı görüşmede ifade ederler.

Böyle bir durumun statik değişkenler ve metotlar yoluyla da oluşturulduğu iddia edilebilir. Statik özelliklerin global yapılar oluşturduğu bir gerçektir fakat statik özellikleri, hakikatten global olmasında fayda olan, hatta global olarak kullanımı, tersi düşünülemeyecek kadar tabi ve gerekli olduğu durumlarda kullandığımız için bu durum singletonlar kadar büyük bir problem görülmez. (Bu konuyu burada ve burada daha detaylı olarak ele almıştık.)

Singleton eleştirileriyle ilgili şu sayfaları paylaşabilirim:

  • Dangers of singleton design pattern
  • Singleton considerations
  • Singleton considered stupid
  • Global state and Singletons
  • Singletons are Pathological Liars
  • Singleton is an anti-pattern
  • Why singletons are evil
  • What is so bad about singletons?
  • Singleton Design Pattern – An introspection and best practices
  • c2.com singleton linkleri
  • Use singletons wisely
  • Do I really need a singleton?
  • Flaw: Brittle Global State & Singletons
  • When is a singleton not a singleton?

Ben şöyle düşünüyorum: Singleton, evet bir tasarım kalıbıdır ama hem gerekliliği hem de teknik kısıtları ya da muhtemel sıkıntıları üzerine ciddi kafa yormadan, işin kolayına kaçarak sıklıkla olur-olmadık yerde kullanılması bence bir istismardır. Singleton güzel ve şıktır ama gelişi güzel ve alışkanlıkla kullanılmayacak kadar da tehlikeli bir çözümdür.

Toplam görüntülenme sayısı: 1343

10 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
14 Şubat 2015

Tasarım Kalıpları: Singleton (Tek Nesne) – III – Enum Kullanımı

Akin Java, Tasarım Kalıpları, Yazılım Modelleme enum, tasarım, tasarım desen, tasarım şablonu

Daha önceki singleton yazılarında, bu kalıbın, alışıla gelmiş haliyle (yani private yapılandırıcı hali) nasıl kurgulandığını ve üzerinde yaptığımız bazı değişikliklerin sonuçlarından bahsetmiştik. Açıkçası bu yazılarda ele alınan yöntem singleton kalıbını oluşturmanın tek yolu da değildir. “enum” yapısını kullanarak da tek bir nesneye sahip bir sınıf oluşturabiliriz.

Malum, “enum” Java’ya SE 5 ile birlikte katılmış anahtar kelimelerdendir. enum, İngilizce’deki “enumeration” yani sıralama kelimesinin kısaltılmış halidir. enum anahtar kelimesiyle, aynı “class” ve “interface” kelimelerinde olduğu gibi yeni bir tip oluştururuz. enum tipinin sahip olabileceği tüm nesneler, enum sınıfı içinde tanımlanırlar. Bu yeni tip aslında özel bir sınıftır ve yapısından dolayı bize getirdiği bazı kısıtları vardır:

  • enum, abstract ya da final olamaz.
  • Her enum, java.lang.Enum‘ın bir alt sınıfıdır.
  • Bir enum tipinin, kendi içinde tanımlanan ve sabite olan, enum nesneleri dışında hiç bir nesnesi yaratılamaz. Bu nesneler de bir enum tipinin metninde ilk sırada gelen üye değişkenler olmalıdır. Yani bir enum sınıfının farklı üye değişkenleri varsa, enum tipinde olan en önce olmalıdır.
  • Tüm enum tipindeki değişkenler otomatik olarak public, static ve final olarak tanımlanırlar.
  • Bir enum tipinin tüm yapılandırıcıları (constructor) private olmak zorundadır, yani bir enum tipinde public ve protected yapılandırıcı tanımlanamaz. Bir enum tipinde varsayılan erişimde bir yapılandırıcı tanımlansa bile bu yapılandırıcı private olur. Hiç yapılandırıcı tanımlanmazsa derleyici bir tane varsayılan private yapılandırıcı tanımlar.
  • Bir enum tipinin yapılandırıcıları çağrılamaz.
  • Bir enum tipinin abstract metodu olamaz. Eğer bir enum tipinin abstract bir metodu olursa, tüm enum değişkenleri bu metodu sınıf içinde ezmek zorundadırlar.
  • enum sabiteleri için parametre geçilebilir, bu durumda bu parametreleri alan yapılandırıcıların olması gereklidir.
  • Bir enum tipinin yapılandırıcıları, o tipteki final olmayan statik üye değişkenlerine ulaşamazlar.
  • java.lang.Enum‘ın “equals()“, “hashCode()” ve “clone()” metotları finaldır.
  • Bir enum tipi, kendi tipindne değişkenler dışında farklı tipte üye değişkenlere sahip olabilir, bu farklı tipteki üye değişkenleri parametre olarak alacak yapılandırıcılara sahip olabilir.

Yukarıda “enum tipinin sahip olabileceği tüm nesneler, enum sınıfı içinde tanımlanırlar” demiştik. Dolayısıyla sadece bir tek nesnesi olan bir enum tip tanımlarsak bu bir singleton olur. Aşağıdaki koda bakalım:

package org.javaturk.dp.pattern.gof.creational.singleton;

public enum EnumSingleton {
		
	SINGLETON;
	
	// In fact no need for this method because SINGLETON is already public.
	public static EnumSingleton getInstance(){
		return SINGLETON;
	}
}

 

Bu durumda istemci kodumuz şöyle olacaktır:

package org.javaturk.dp.pattern.gof.creational.singleton;

public class EnumSingletonClient {

	public static void main(String[] args) {
		EnumSingleton instance1 = EnumSingleton.SINGLETON;
		EnumSingleton instance2 = EnumSingleton.getInstance();
		
		if(instance1 == instance2)
			System.out.println("The same!");
		else
			System.out.println("Different!");
		
	}
}

 

EnumSingletonClient sınıfındaki main metot çalıştırıldığında ise konsola “The same” yazılacaktır.

Yukarıdaki enum sınıfında, daha önceki yaygın singleton sınıflarında olduğu gibi “private static int count;” tanımlayıp yapılandırıcıda da “count++; name = “Singleton” + count;” cümleleri ile değerini arttırıp, nesnenin name özelliğini belirleme  yoluna gitmedik, daha doğrusu gidemedik çünkü yukarıda da yazdığımız gibi enum tipinin yapılandırıcıları, o tipteki final olmayan statik üye değişkenlerine ulaşamazlar.

Açıkçası, sonradan çıkmış olmasına rağmen enum tipini kullanan bu yaklaşımın önce ele aldığımız yaygın yaklaşıma bazı üstünlükleri vardır. Çünkü yaygın yaklaşımda, singleton olan nesneden daha fazla nesne yaratmak bazı özel durumlarda söz konusudur. Örneğin reflection kullanarak yapılandırıcısı private olsa bile yeni nesneler oluşturabilirsiniz. Ya da “clone()” metodunu kullanarak var olan nesnenin kopyalanması söz konusudur. Ayrıca singleton olan nesneyi serialized yapıp, sonra deserialized yaparsanız, elinizde bir başka nesne daha oluşacaktır. Bu üç durum genel olarak yaygın olan yaklaşımın en problemli olan üç noktasıdır. Ayrıca yaygın yaklaşımda sonradan yüklemeli durumu tercih ettiğinizde, “synchronized” ve “volatile” anahtar kelimelerini kullanmazsanız başınızın derde gireceğini daha önce burada göstermiştik. Dolayısıyla enum kullanan singleton, eğer yukarıdaki kısıtlar sizi zorlamıyorsa, yaygın yapıya göre çok daha güvenli ve kullanışlıdır. Nitekim Jashua Block “Effective Java” isimli güzel kitabının ikinci baskısındaki singleton tartışımasın şöyle bitiriyor:

“This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.”

 

Toplam görüntülenme sayısı: 1928

7 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
13 Şubat 2015

İlk C# Programım ve Mac’de Mono

Akin Bilgisayar Bilimleri C

Dün internette gezinirken, “C# Design Patterns Essentials” isimli Amazon’da bayağı beğenilmiş bir kitaba rastladım ve biraz okumaya başladım. Sonra aklıma geldi, burada yayınladığım tasarım kalıpları ile ilgili Java kodlarının C# karşılıkları nasıl olur diye merak ettim. O sırada “C# on Mac OS” diye bir arama yaptım ve 15-20 dakika içinde kendimi Mac’imde basit bir editörle C# yazıp, terminalde mono ile derleyip çalıştırırken buldum 🙂

Açıkçası Java eğitimlerinde karşılaştığım C# arkadaşlara örnek vermek anlamında ara sıra C# kitaplarına bakıyordum ama sanırım hiç C# kodu yazmamıştım. Bence makinamda bir C# ortamı olması güzel. Belki bazı kalıplar için C# kodlarını da yazarım, kıyaslarım Java ile vs. Kıyaslamak insana çok daha güzel düşünme imkanı sağlıyor. Bu açıdan uzmanı olmasak bile farklı dillere en azından aşina olmak, oradaki yapılardan haberdar olmak güzel bir şey, ufuk açıcı.

Programlama dilleriyle ilgili sevgi ve beğeniyi bağımlılık durumuna getirmemek lazım. Sonuçta hiç birisi amaç değil, araç. Ama amacı gerçekleştirmek için iyi bilinmesi gereken araçlardan. Öyle her altı ayda bir yeni dil öğrendim denilecek cinsten şeyler değil, üstadı olmak için seneler verilen şeyler. Öyle Bilgisayar Mühendisliği’nde okuyan 20 yaşındaki bir gencin CVsine ard arda C, C++, Java, Ruby, Python, C# diye, “Çok İyi” ya da “İyi” dereceleriyle sıralanacak cinsten değil bu teknolojiler 🙂 Uzmanı olmak ciddi zaman, emek ve disiplinli öğrenme gerektiren şeyler. Tek başına zaman harcamak da bir insanı bir dilde çok iyi duruma getirmiyor açıkçası, üzerinde sistemli bilgilenme, düşünme olmadan, alelade bir programcılık emeği, insanı o dilde üstad yapmıyor. Farklı dillerle uğraşılmasa bile onlar hakkında okumak, ufak tefek kıyaslamalar ve bilgilenmeler yapmak bence bu açıdan önemli.

Neyse, C#’a dönersek tabi ki ilk yazdığım kod hem nesne-merkezli hem de “Selam” olur 🙂 Şöyle:

using System;

public class Selam{

	public string selamSoyle(string kime){
		return "Selam " + kime + " :)";
	}

	public static void Main(){
		Selam nesne = new Selam();
		string cevap = nesne.selamSoyle("Akin");
		Console.WriteLine(cevap);
	}
}

 

Beni tanıyanlar bilirler, ilk örneğimde bile statik yapılarla yetinmem, muhakkak nesne kullanırım. Öte taraftan “Hello World” ve “foo” gibisinden isimlere de gıcığım zaten. Kodlarımızı daima Türkçe yazalım demiyorum ama en azından ilk örneğimizde “hello” yerine “selam” demek çok daha tabi.

C# yazarken metot isimlerinin büyük harfle başlaması, benim en zorlandığım kısım oldu. Bu yüzden “selamSoyle()“i Java’daki gibi yazdım. Bence C#’ın bu konuda farklı bir standart benimsemesi pek anlaşılır değil, okuma kolaylığı sağlamıyor açıkçası, az da olsa yapılandırıcılarla karışma riski var.

Bir diğer garipsediğim nokta da “System” paketini kullanmak için “using System;” diye belirtmek zorunda olmam oldu. Sanki bunun gibi çok temel bir paketin otomatik olarak kullanılabilir olmasını bekledim, Java’daki “java.lang” paketi gibi.

Bir de küme parantezlerini koyduğum yerler var tabi, Java kodunu andıran 🙂 Bunun dışında her şey şimdilik güzel görünüyor.

C# ile ilgili yazı yazacağımı rüyamda görsem inanmazdım 🙂 Ama işte hayat bu, ne oldum demeyeceksin, ne olacağım diyeceksin 🙂 Dün bu konuda tweet atınca bir arkadaşım, “Yaptigin denemenin iler tutar hicbir yani yok… Anlik bir kendini kaybetme diyelim, unutalim…” ve “Mac de, C# ogrenen Java danismani mi olurmus Akin Hocam :-)))” yazmış. Haklı tabi, ben bir an hemen Twitter ve Google ile irtibata geçip, “abi silin, kazıyın şu tweeti evrenden” diyecek oldum açıkçası 🙂 Ama sonra kendime geldim, bu kadar C#’ın bir zararı olmaz diye düşündüm 🙂

 

Toplam görüntülenme sayısı: 1104

9 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
12 Şubat 2015

Tasarım Kalıpları: Proxy (Vekil) – IV

Akin Java, Tasarım Kalıpları, Yazılım Modelleme design pattern, tasarım deseni, tasarım örüntüsü nedir, tasarım şablonu

Proxy tasarım kalıbıyla ilgili bir önceki yazıda, bu kalıp ile ilgili ikinci örneğimizi, ağ yapılarındaki proxy kullanımını simule etmiştik çünkü bizim yazılımda proxy kalıbıyla yapmaya çalıştığımız şey aslında yıllardır ağlarda güvenlik amacıyla kontrol ve filtreleme yapan proxylerin yaptığı şeydi. Şimdi bu konudaki son örneğimizle devam edelim.

GoF kitaplarında, proxy kalıbıyla ilgili örnek olarak içerisinde büyük hacimli resimlerin (image) olduğu bir metin dokümanını verir. Örnek yapıda, metin dokümanı açılırken yani belleğe yüklenirken, içerisinde var olan büyük hacimli resimlerin de yüklenmesini istemenin ciddi bir yaratma ve yükleme maliyeti yaratacağından bahsedilir. Bundan dolayı teklif edilen, metni görüntüleyenin, dokümanda gerçekten bu resimlere gelinceye kadar, resimlerin yüklenmesini geciktirmektir. Muhakkak böye bir yaklaşım metni daha hızlı belleğe yükleyecek ve kullanıcının metin üzerinde dolaşmasını ve onu kullanmasını daha rahat kılacaktır. Bu durumda yapılacak şey, metin dokümanı yüklenirken, resimlerin doğrudan belleğe yüklenmesi yerine, proxy yani, o resimler yerine geçen vekil nesnelerin ya da daha açık ifadeyle örneğin ikon gibi, İngilizce’de “placeholder” denen, o resmin olduğunu belirten “yer tutucu”ların yüklenmesidir. Yer tutucu nesne aşağıdaki şekilde “anImageProxy” olarak görüntülenmiştir.

ProxyDocument1

Bu noktada dikkat edilmesi gereken şey, gerçek resimler yerine yer tutucuların yüklendiğini, metnin bilmemesi gerektiğidir. Bu şekilde yer tutucu yani vekil resim (burada sanırım vekillikten ziyade “göstermelik” kelimesi daha anlamlı oluyor)  kullanmanın, metnin yapısında hiç bir değişikliğe sebep olmaması gereklidir. Bunu sağlamanın yöntemi ise gerçek nesne ile vekilinin aynı arayüze sahip olmasıdır. Eğer bu nokta atlanırsa, proxy nesnesi, doğrudan arada bulunan ve varlığından özellikle vatandaş ya da bu örnekteki metin dokümanı gibi müşteri (client) nesnelerinin tamamen haberdar olduğu, basit al-ver (delegation) yapan nesneye dönüşür ki bu durumda da zaten “program to an interface, not an implementation” prensibini ıskalamış oluruz.

Bu kalıp bu olaya uygulandığında aşağıdaki diyagrama ulaşırız:

 

ProxyDocument2

Yukarıdaki şekile bakarken, GoF’un kitabı yazılırken UML’in henüz tamamlanmadığı gerçeğini göz önüne almalıyız. Ayrıca GoF örneklerini C++ ile verdiklerinden şekildeki kod parçaları bu dildedir. Biz bu yapıyı Java ile yazarsak kodlarımız şöyle olacaktır:

Image, arayüzdür:

package org.javaturk.dp.pattern.gof.structural.proxy.image;

public interface Image {
	public void draw();
	public void erase();
}

 

BigImage, yüklenmesini geciktirdiğimiz büyük resim nesnemizdir.

package org.javaturk.dp.pattern.gof.structural.proxy.image;

public class BigImage implements Image {

	public void draw() {
		System.out.println("Drawing the big image");
	}

	public void erase() {
		System.out.println("Erasing the big image");
	}
}

 

ImageProxy ise vekil resim nesnesidir:

package org.javaturk.dp.pattern.gof.structural.proxy.image;

public class ImageProxy implements Image {
	
	private BigImage bigImage;

	public void draw() {
		if(bigImage == null)
			bigImage = new BigImage();
		bigImage.draw();
	}

	public void erase() {
		bigImage.erase();
	}
}

 

ImageChooser ise singleton resim gösteren nesnedir.

package org.javaturk.dp.pattern.gof.structural.proxy.image;

public class ImageChooser {
	
	private static ImageChooser ic = new ImageChooser();
	private Image image;
	
	public ImageChooser(){
		image = new ImageProxy();
	}
	
	Image getImage(){
		return image;
	}

	public static ImageChooser getInstance(){
		return ic;
	}
}

 

Document ise, sadece main metoda sahip olan metin nesnemizdir:

package org.javaturk.dp.pattern.gof.structural.proxy.image;

public class Document {

	public static void main(String[] args) {
		ImageChooser imageChooser = ImageChooser.getInstance();
		Image image = imageChooser.getImage();
		
		double chance = Math.random();
		if(chance > 0.9)
			image.draw();
	}
}

 

Document nesesinin main metodundaki “if” yapısı, gerçekte BigImage nesnesinin yüklenmesinin sanki %10’luk bir ihtimal dahilinde olacağını göstermek için konmuştur.

Toplam görüntülenme sayısı: 1375

8 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
«< 22 23 24 25 26 >»

Günlüğüme Hoşgeldiniz

Bu günlükte, Yazılım Mühendisliği, Bilgi Teknolojileri, Java, kişisel gelişim ve zaman zaman da diğer konulardaki düşüncelerimi sizlerle paylaşacağım. Umarım beğenir ve hoşça vakit geçirirsiniz.

Her türlü düşüncenizi, yorum olsun, beğeni ya da eleştiri olsun, bana iletmenizi rica ediyorum sizden. Ayrıca bana akin@javaturk.org adresinden ya da Twitter'dan ulaşabilirsiniz. Videolarıma da buradan ulaşabilirsiniz.

Teşekkür ederim.

Akın Kaldıroğlu

Rahat Okumak İçin

A Decrease font size. A Reset font size. A Increase font size.

Sosyal Medya

  • Twitter
  • Facebook
  • LinkedIn
  • Youtube

Son Twitlerim

→ Takip Etmek İçin

Abone Olun

Emalinizi girerek yazılardan haberdar olun.
Loading

Son Yazılarım

  • Udemy Eğitimlerim Üzerine
  • (başlıksız)
  • Clean Code / Temiz Kod Eğitimi Udemy’de
  • Java ile Nesne-Merkezli Programlamaya Giriş Eğitimi Udemy’de
  • Selsoft Video Eğitimleri
  • Spring ile Kurumsal Yazılım Geliştirme
  • Corona Günlerinde Design Patterns
  • Corona Günlerinde Java
  • JDK 10 ve “var” Özelliği
  • Onur Özcan
  • Analist ve İş Bilgisi
  • Farklı Dillerin Bakış Açısıyla Nesne-Merkezli Programlama
  • Java Nedir?
  • Bilgi Teknolojilerinde Yetenek Yönetimi – II: Tanımlar ve Eleştiriler – I
  • Alelade Hikayeler – II: Bir Başka Performans Problemi

Yazı Kategorileri

Yazı Takvimi

Mart 2026
P S Ç P C C P
 1
2345678
9101112131415
16171819202122
23242526272829
3031  
« May    

Yazı Arşivi

Blogroll

  • Binnur Kurt'un Günlüğü
  • Ender'in Java Blogu
  • Erdem Seherler
  • Kızımın Günlüğü
  • Kurumsal Java
  • Levent Karagöl
  • Levent'in Java Blogu
  • Mert Can Akkan’s java tips,options, news…
  • Yaşar Safkan
  • Yasin Saygılı
  • Yazı Dünyası

Yazı Etiketleri

analiz Bilmek C Desen design pattern EJB Eğitim Fortran Hibernate Java Java'ya nasil baslarim Java dersleri Java EE Java Persistence API Java SE Java Sertifika Java Öğren Java öğreniyorum Java öğrenmek JPA Kalıp Kurumsal Java nesne nesne-merkezli No Silver Bullet object object-oriented Oracle Java Certifications pattern performans programlama programlama dilleri programlama nedir sertifika singleton tasarım tasarım deseni tasarım desenleri tasarım şablonu yazılım yazılım geliştirme Yazılım Mühendisliği yazılımın doğası yazılımın zorlukları Şablon

↑

© Java Günlüğüm 2026
Powered by WordPress • Themify WordPress Themes
 

Yorumlar Yükleniyor...