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
12 Mart 2015

Tasarım Kalıpları: Factory Method (Üretici Metot) – II

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

Bir önceki yazıda Factory Method kalıbına giriş yapmıştık ve sınıf diyagramı ile tipik bir uygulamasını görmüştük. Şimdi bu uygulamanın kodlarına kısaca göz atalım.

Önce Product yapısına bakalım:

public interface Product {
	
	public void doThis();

}


public class ProductA implements Product {

	private int id;
	private String name;
	
	public ProductA(int id, String name) {
		this.id = id;
		this.name = name;
	}

	@Override
	public void doThis(){
		System.out.println("do() in ProductA");
	}
        ...
}


public class ProductB implements Product {
	
	private int no;
	private String description;
	
	public ProductB(int no, String description) {
		this.no = no;
		this.description = description;
	}

	@Override
	public void doThis(){
		System.out.println("do() in ProductB");
	}
        ...
}

Şimdi de bu Product yapısındaki nesneleri oluşturan üretici metotlara bakalım:

 

public interface Factory {
	public Product create();
}


public class ProductAFactory implements Factory {

	@Override
	public Product create() {
		ProductA productA = new ProductA(1, "Product-A-1");
		return productA;
	}
}


public class ProductBFactory implements Factory {

	@Override
	public Product create() {
		ProductB productB = new ProductB(2, "Product-B-2");
		return productB;
	}
}

 

Bu durumda Client ve Test nesneleri de şöyle olur:

 

public class Client {
	
	private Product productA;
	private Product productB;
	
	private Factory productAFactory;
	private Factory productBFactory;
	
	public Client(Factory productAFactory, Factory productBFactory){
		productA = productAFactory.create();
		productB = productBFactory.create();
	}
	
	public void start(){
		productA.doThis();
		productB.doThis();
	}
}

 

public class Test {

	public static void main(String[] args) {
		Client client = new Client(new ProductAFactory(), new ProductBFactory());
		client.start();
	}
}

 

Hem bir önceki yazıda verdiğimiz sınıf diyagramı hem de yukarıdaki kodlardan anladığımıza göre artık  Client’ın Product’ları doğrudan yaratmak yerine, bunu üretici metotlara havale ettiğini ve Product’larla arayüzleri üzerinden haberleştiğini görüyoruz. Bu durum ise Factory arayüzünü yerine getiren ve üretici metotlara sahip üretici sınıflarla başarılır. Bu şekilde Client’ın hem Product’lara hem de onları üreten Factory’lere bağımlılığı arayüz seviyesine iner.

Factory arayüzü sayesinde, uygulamadaki sınıflar, bu sınıfları kullanan client kodlarından olabildiğinde yalıtılmış olur. Bu yaklaşımın en temel problemi, her yeni Product sınıfı için yeni bir Factory alt sınıfa ihtiyaç duyurmasıdır. Yani, yeni bir Product nesnesi olan ProductC için ProductCFactory alt sınıfına ihtiyaç duyulur.

Bu kalıp üzerinde ihtiyaca göre bazı oynamalar tabi olarak yapılabilir. Örneğin Factory tipi arayüz ya da soyut (abstract) sınıf yerine somut (concrete) sınıf da olabilir. Bu durumda create() factory metodu parametre alarak, hangi Product nesnesinin yaratılacağına karar verebilir. Ve her yeni Product nesnesi için yeni bir factory nesnesine ihtiyaç da kalmaz. Bu durumda Factory sınıfı Singleton da olabilir ve istenirse farklı implementationlar için Factory sınıfı hala extend edilebilir. Bu durumdaki Factory sınıfı ile factory metodu ve Client aşağıda olduğu gibidir.

public class Factory {
	
	public Product create(String productType){
		Product product = null;
		if(productType.equalsIgnoreCase("a"))
			product = new ProductA(1, "Product-A-1");
		else if(productType.equalsIgnoreCase("b"))
			product = new ProductB(2, "Product-B-2");
		return product;
	}
}

public class Client {
	
	private Product productA;
	private Product productB;
	
	public Client(Factory factory){
		productA = factory.create("a");
		productB = factory.create("b");
	}
	
	public void start(){
		productA.doThis();
		productB.doThis();
	}
}

Yukarıdaki durumun bir özel hali olarak, client, kullanacağı nesnenin yaratılması için gerekli bazı bilgileri sağlama durumunda olabilir. Bu durumda yukarıdaki örneğe benzer şekilde client, üretici metoda bu bilgileri geçmelidir. Burada dikkat edilmesi gereke husus, clientın geçeceği bu bilgileri hakikatten sadece clientın biliyor olmasıdır. Factory methodun da erişebileceği bilgileri clientın geçmesi hem anlamlı değildir hem gereksiz bağımlılık oluşturarak bu kalıbı kullanmaktan doğan faydayı azaltır.

Bu kalıbın çok sıklıkla, Factory sınıfının üzerindeki factory metotlarını statik yaparak kullanılması da söz konusudur. Bu durumda Client sınıfı Factory sınıfının nesnesini oluşturmak zorunda kalmaz ve Factory sınıfının alt sınıflarını oluşturmaktan da kaçınılmış olur.

public class Factory {
	
	public static Product create(String productType){
		Product product = null;
		if(productType.equalsIgnoreCase("a"))
			product = new ProductA(1, "Product-A-1");
		else if(productType.equalsIgnoreCase("b"))
			product = new ProductB(2, "Product-B-2");
		return product;
	}
}
public class Client {
	
	private Product productA;
	private Product productB;
	
	public Client(){
		productA = Factory.create("a");
		productB = Factory.create("b");
	}
	
	public void start(){
		productA.doThis();
		productB.doThis();
	}
}


Bu yaklaşımın problemi, büyüyebilen (scalable) olmamasıdır. Yani oluşturulacak nesnelerin sayısı arttıkça, iflerin sayısı da artacaktır. Dolayısıyla bu çözüm zaten Open-Closed Principle ( OCP)’a aykırıdır. Hatta bir müddet sonra ilgili-ilgisiz her türlü nesnenin kendisiyle oluşturulduğu devasa bir metota sahip olabilirsiniz. Dolayısıyla bu yaklaşım bir ters-kalıptır (anti-pattern). Eğer birbiriyle ilgili birden fazla nesneyi yaratma probleminiz varsa bu durumda zaten Abstract Factory kullanılabilir.

Factory Method’un her zaman nesne oluşturması gerekmez. Nesne havuzu (object pool) gibi yapılarda Factory Method havuzdan bir nesne de geri döndürebilir.

J. Bloch “Effective Java 2nd Ed.” isimli kitabının ilk maddesinde, yapılandırıcı kullanmak yerine statik factory metotları kullanmayı tavsiye ediyor. Çünkü metotların ismi olmasına karşın yapılandırıcıların ayırt edici isimleri yoktur. Ve özellikle de karmaşık nesnelerde pek çok yapılandırıcı vardır ama hangisinin çağrılacağı çok zaman zaman alan bir kodlama gerektirir.

Sonuçlar

Factory Method kalıbı, nesne yaratma işinin kontrolünü sisteme bırakarak, clientın sadece kullanmak istediği nesneleri istemekle yetinebileceğini göstermektedir. Bir nesneyi kullanmayı bilmek o nesnenin arayüzünü (interface) bilmek anlamına gelmektedir. Yapılandırıcılar çoğu kez karmaşık metotlardır ve çağrılabilmeleri için pek çok bilgiye ihtiyaç duyarlar. Bu bilgileri toparlamanın sorumluluğu olabildiğince client tarafında olmamalıdır. Client, nasıl yaratıldığını bilmeden nenelerle haberleşebilmelidir. Bu kalıp ile bu esneklik sağlanır.

Aynı zamanda client da Product nesnelerinin gerçek tiplerini bilmek zorunda olmadan onlarla haberleşebilmektedir: Polymorphism!

Kullanımlar

Java APIlerinde Factory Method’un pek çok kullanımı vardır.

  • java.sql paketinde Connection üzerinde createStatement() metotları farklı Statement nesneleri üretilir.
  • Aynı paketteki Statement üzerindeki executeQuery() metodu ile de ResultSet nesnesi üretilir.
  • javax.persistence paketinde EntityManagerFactory üzerindeki createEntityManager() metotları EntityManager nesneleri üretir.

Bazen factory metodunun statik olduğu da görülür:

  • java.sql.Driver getConnection()
  • javax.persistence.Persistence createEntityManagerFactory()
  • java.util.Calendar getInstance()
  • java.util.ResourceBundle getBundle()
  • java.text.NumberFormat getInstance()

Buradaki amaç factory methodunun override, içindeki sınıfın da extend edilmesini önlemektir.

Diğer Kalıplarla İlişkiler

Factory Method, Abstract Factory kalıbında sıklıkla kullanılır. Somut sınıfla gerçekleştirilmesi durumunda Factory Method, bir Singleton içinde bulunabilir.

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

10 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
11 Mart 2015

Tasarım Kalıpları: Factory Method (Üretici Metot) – I

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

Factory method ya da Türkçesiyle üretici metot, muhtemelen programcılık tecrübesi içerisinde programcıların tabi olarak ihtiyacını ilk defa hissettikleri kalıptır. Çünkü bu kalıp, nesnelerin yaratılmalarını soyutlamakta ve üretici metot dediğimiz factory metoduna havale etmektedir.

GoF’da bu kalıbın amacı için şu denmektedir:

Intent: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Amaç: Bir nesne yaratmak için bir arayüz tanımla, fakat hangi sınıfın nesnesinin oluşturulacağına alt sınıflar karar versin. Factory methodu bir sınıfın nesne oluşturmasını alt sınıflarına ertelemesine izin verir.

Problem

Nesne-merkezli programlardaki tabi olarak en temel iş, nesne yaratmaktır. Uygulamalarda farklı karmaşıklıkta pek çok sınıf vardır ve bu sınıfların nesneleri uygulamanın farklı yerlerinde oluşturulur. Bu kalıp, nesnelerin yaratılmalarını soyutlamakta ve bu işi “üretici” ya da “factory” metoda havale etmektedir. Factory method, nesnelerin yaratılmasından sorumlu bir metottur öyle ki bir arayüzün alt sınıfında bulunur.

Client’ın, Product nesnelerinin sadece arayüzlerini değil aynı zamanda nasıl yaratılacaklarını da bilmesi, Client’ın Product’lara olan bağımlılığını arttırır. Çoğu zaman bir nesneyi yaratmak, onu kullanmaktan daha karmaşıktır.

Aşağıdaki diyagramda, Client ile Product nesneleri arasında, doğrudan yaratmaya bağlı ilişki ifade edilmiştir.

Klasik Client-Product ilişkisi.

Klasik Client-Product ilişkisi.

Bu duruma karşılık gelen ProductA ve ProductB kodları şöyledir:

package org.javaturk.dp.pattern.gof.creational.factoryMethod.product.old;

public class ProductA {
	private int id;
	private String name;
	
	public ProductA(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public void doThis(){
		System.out.println("do() in ProductA");
	}

	public int getId() {
		return id;
	}
        ...
}

ve

package org.javaturk.dp.pattern.gof.creational.factoryMethod.product.old;

public class ProductB {
	private int no;
	private String description;
	
	public ProductB(int no, String description) {
		this.no = no;
		this.description = description;
	}

	public void doThis(){
		System.out.println("do() in ProductB");
	}

	public int getNo() {
		return no;
	}
	...
}

ve Client da:

package org.javaturk.dp.pattern.gof.creational.factoryMethod.product.old;

public class Client {
	
	private ProductA productA;
	private ProductB productB;
	
	public Client(){
		productA = new ProductA(1, "Product-A-1");
		productB = new ProductB(2, "Product-B-2");
	}
	
	public void start(){
		productA.doThis();
		productB.doThis();
	}
}

 

Çözüm

Bu yüzden Client’ın Product’ları doğrudan yaratmak yerine, bunu üretici metotlara havale etmesi ve Product’larla arayüzleri üzerinden haberleşmesi daha rahattır. Bu ise Factory arayüzünü yerine getiren ve üretici metotlara sahip üretici sınıflarla başarılır. Bu şekilde Client’ın hem Product’lara hem de onları üreten Factory’lere bağımlılığı arayüz seviyesine iner.

Factory method kalıbından sonraki ilişki

Factory method kalıbından sonraki ilişki

 

Bir sonraki yazıda Factory Method ile geliştirdiğimiz çözümün kodlarına bakacağız.

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

17 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
08 Mart 2015

Bilişim Sohbetleri

Akin Eğitim ve Seminer

Sevgili arkadaşlar, haftaya yani 14 Mart 2015 Cumartesi günü saat 21:00’da Bilişim Sohbetleri’nde olacağım. Mimar Aslan ve Çağdaş Öğüt beylerle “Clean Code”u konuşacağız.Canlı yayın adresi: https://www.youtube.com/watch?v=OqIOQNfPebk

Beklerim efen’im.

 

bilisimsohbeti

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

10 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
04 Mart 2015

Yazılımı Anlamak Üzerine

Akin Bilgisayar Bilimleri, Yazılım Mühendisliği anlamak, design pattern, Kalıp, pattern, Şablon, yazılım

C++’ın babası olan Bjarne Stroustrup, “The C++ Programming Language” isimli kitabında şöyle der: “Design and programming are human activities; forget that and all is lost.” ya da Türkçesiyle: “Tasarım ve programlama insani işlerdir; bunu unutun, herşey kaybolur. ”

Ben bu cümleyi eskiden bu yana şöyle anlıyorum: Yazılımı tasarlamak olsun, programlamak olsun, öyle uzaylıların yaptıkları işler değildir, tamamen insani faaliyetlerdir, fırıncının ekmeğini yapması gibi ya da futbolcunun futbolunu oynaması ya da bir öğretmenin öğrencilerini eğitmesi gibi, doğrusuyla, yanlışıyla, tamamen insan ve tabi çevresinin işin içinde olduğu faaliyetlerdendir. Eğer bu geçeği unutursak, yazılımı geliştirmeyi, elit, ayrık yani doğal insani ortamından koparılmış gibi ele alırsak, ortada yazılım falan kalmaz. Nitekim üstad bu cümleyi şöyle bir paragrafta söylüyor:

“Too often, we forget the human aspects of system building and consider the software development process as simply ‘‘a series of welldefined steps, each performing specific actions on inputs according to predefined rules to produce the desired outputs.’’ The very language used conceals the human involvement! Design and programming are human activities; forget that and all is lost.”

Yani

“Çok sıklıkla, sistem inşa etmenin insani taraflarını unutuyoruz ve yazılım geliştirmeyi “önceden tanımlanmış kurallara göre girilen verilerden istenen çıktıları üretmek için özel işlemleri yapacak şekilde kurgulanmış, her biri iyi tanımlanmış adımlardan oluşan bir seri” gibi düşünüyoruz. Kullanılan programlama dilinin kendisi, insanın katkısını saklıyor. Tasarım ve programlama insani işlerdir; bunu unutun, herşey kaybolur.”

Evet yazılımı tasarlarken ya da geliştirirken, fildişi kulelerde, her türlü şeyin düşünüldüğü, son derece formal ortamlarda çalışmıyoruz biz. Bakkal Hasan amcanın kendi ortamında bir problemi çözerken kullandığı araçlar ve yöntemlere benzer şeyler kullanıyoruz biz de. Durum Amerikan filmlerinde gördüğümüz şu cümleyle de güzel bir şekilde açıklanabilir: “It is not rocket science!”

Stroustrup’un yukarıdaki paragraftaki şu cümlesi bizim yazılıma sanki uzaydan gelme bir şeymiş, rocket sciencemış gibi davranmamızın sebebini açıklıyor sanırım: “Kullanılan programlama dilinin kendisi, insanın katkısını saklıyor.” Yani kullandığımız programlama dilleri, araçlar, sistemler vs. aşırı karmaşık ve matematiksel yapısından dolayı olayı yani yazılım geliştirmeyi, mistik, kaotik ve esoterik, sadece ehlinin anlayacağı bir iş, olarak görmemize, kurgulamamıza ve dışarıya yansıtmamıza sebep oluyor. Yani yazılımcılar olarak bizler sanki sabah akşam kapalı kapılar ardında, orta çağın büyücüleri gibi, başkalarının gördüğünde “vuuuuuuu, çok etkilendiiimmm” cinsinden laflar söyleyeceği işler yapıyoruz. Halbuki üstad diyor ki, bu bir yanlış anlamadır, kullandığımız dil vb. araçlar böyle bir algı oluşturabilir ama bu yanlıştır. Her insani faaliyet gibi yazılım geliştirme de son derece insanidir. Örneğin şunu diyor Stroustrup:

“…

–  There are no ‘‘cookbook’’ methods that can replace intelligence, experience, and good taste in design and programming.

–  Experimentation is essential for all nontrivial software development.

…

It is easy –  and typically expensive –  to underestimate any of these points. It is hard to transform the abstract ideas they embody into practice. The need for experience should be noted. Like boat building, bicycling, and programming, design is not a skill that can be mastered through theoretical study alone.”

Yani

“…

–  Tasarım ve programlamada insan zekası, tecrübesi ve estetiğinin yerine geçebilecek hiç bir reçete metot yoktur.

–  Deneme – yanılma, basit olmayan her yazılım projesi için asıldır.

…

Bu noktaları gözden kaçırmak kolaydır ve sıklıkla pahalıdır. Soyut fikirleri pratiğe dökmek zordur. Tecrübeye olan ihtiyacımıza dikkat edilmelidir. Gemi inşa etme, bisiklete binme ve programlama gibi tasarım da sadece teorik çalışmayla elde edilebilecek bir yetkinlik değildir.”

Peki neden durup dururken bunlardan bahsediyorum ki? Yazılım ile ilgili olarak çalışırken, tasarlarken ya da programlarken sıklıkla, bağlamımızı aşırı soyut tuttuğumuzu ve bu durumun da problemi anlamakta dolayısıyla da doğru düzgün bir çözüm üretmekte bize sıkıntı çıkardığını görüyorum. Eğer problemimizi bir insani durumun sonucu olarak ele alıp, daha anlaşılır bir ifadeyle, problemimizi yeryüzüne indirip, tamamen günlük hayattan figürlerle ifade edemediğimizde, durumu anlamakta ciddi bir sıkıntıya girdiğimizi hatta doğrudan problemi ıskaladığımızı düşünüyorum.

Ne demek istediğimi size bir örnekle açıklayayım: Yazılımla alakalı kavramları ya da teknikleri anlatırken, bu kavram ve teknikleri ne kadar örneğin benimle çevremdeki insanlar arasındaki ilişkiler ya da iyi bilinen bir filmde resmedilmiş ve akılda kalmış sahne cinsinden ifade edebilirsem, insanların beni o kadar rahat anladıklarını görüyorum. Daha anlaşılır şekilde örneğin, sıklıkla tasarım kalıplarını (design patterns) hem anlatma hem de uygulama durumunda kalıyorum, eğitimlerde ya da danışmanlıklarda. Proxy (vekil) tasarım kalıbını ele alalım mesela. Bu kalıbı, tamamen yazılım kavramları üzerinden anlatmaya çalıştığımda, insanların, yazılımcıların yani, anlar gibi görünmelerine rağmen, gerçekte anlamadıklarını farkediyorum. Nasıl anlıyorum bunu? Onlara bir problem verip bunu az önce anlattığım proxy kalıbıyla çözmelerini istediğimde, yazılımcıların yarısından fazlası çözmekte zorlanıyor. Ama aynı kalıbı buradaki örnekte olduğu gibi, başbakan ve vatandaşlar cinsinden anlattığımda ise aynı kişilerin daha başarılı bir şekilde bu çözümü yeni durumlara uygulayabildiklerini farkettim. Bu durum Stroustrup’un şu cümlesiyle daha rahat anlaşılabilir: “Soyut fikirleri pratiğe dökmek zordur. Tecrübeye olan ihtiyacımıza dikkat edilmelidir. Gemi inşa etme, bisiklete binme ve programlama gibi tasarım da sadece teorik çalışmayla elde edilebilecek bir yetkinlik değildir.”

Evet yazılım soyuttur ama neticede bu dünyadandır ve zihnimizin “benzerlikler üzerinden çalışma” yeteneğinden faydalanarak, soyut olan yapıları somut, elle tutulan ve gözle görülenler cinsinden ifade ederek, daha insani boyuta indirgeyebiliriz. Çünkü proxy tasarım kalıbının çözdüğü şey ile bir insanın bir başka insana örneğin bir avukata vekalet vererek çözdüğü aslında aynı şeydir, aynı problemdir. Tıpkı, visitor (ziyaretçi) kalıbının çözdüğü problemin, örneğin bir evdeki kişilerin hepsinin ayrı ayrı terziye giderek ölçü verip elbise diktirmeye kalkmalarının yarattığı enerji kaybı ve bürokrasiyi ortadan kaldırmak amacıyla, terziyi eve çağırmalarıyla aynı olması gibi.

Tüm bu “insani” yaklaşımlar, problemin kendisini anlamaya yönelik çalışmalardır. Yazılımın soyut bir yapıda olması, yazılımı anlamak ve çözümlemek için tamamen soyut yapılardan hareket etmemizi gerektirmez. En azından problemi tanımlayıncaya ve ona her boyutuyla hakim oluncaya kadar, problemi soyut düzlemden somut ve insani düzleme çekebiliriz. Böyle bir yaklaşım bize daha aşina olduğumuz bir zeminde hareket etme kabiliyeti vereceği gibi “Deneme – yanılma, basit olmayan her yazılım projesi için asıldır.” şeklindeki prensipleri, hem yazılıcıların hem de yöneticilerinin anlamalarını sağlayacaktır.

Üstadlardan öğreneceğimiz çok şey var.

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

11 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
«< 20 21 22 23 24 >»

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...