17 Kasım 2008 Pazartesi

Giriş düzeyinde ‘Java Job’

Quartz, açık kaynak(open source) projedir amacı Java’da iş sırasını süreç dahilinde mantıksal bir sisteme oturtmaktır. 300’e yakın sınıf ve 12 paket yapısından oluşmaktadır. Basit anlamda ise çekirdek Quartz; Job, Schedular adından iki interface ve JobDetail, Trigger adında iki sınıftan oluşmaktadır.

Basit bir örnekle kodlamaya başlayalım. Job interface’ni implement eden MessageJob sınıfını yaratalım. Job interface’i execute() adından tek bir metod içermektedir. JobExecutionContext nesnesine referans olan parametre almaktadır, bu parametre sınıfın tetiklendigi yerden gelen verilere ulaşmamızı sağlar. Vereceğimiz örnekte daha da net anlaşılacağını umuyorum.


StdSchedulerFactory.getScheduler() bize Scheduler instance’ını döndermektedir. Scheduler çalıştırılabilir (start), durdurulabilinir (stop) ya da bekletilebilir (pause) statelerinde olabilir. start() edilerek başlanır. JobDetail sınıfını yaratalım. 3 parametreye gereksinim duyar. Job’ın ismi, Job’ın dahil edilmek istenen grubu ve son parametre ise Class, hangi job sınıfı olduğu. Trigger sınıfını yaratalım, SimpleTrigger veya CronTrigger. Trigger yapılandırıcına geçirilmesi gereken parametreler’e gelelim. Ilk parametre tetikleyicinin adı, ikincisi tetikleyicinin grubu, unutmamak gerekirki tetikleyicinin adı grup içerisinde biricik olmalıdır. 3. parametre ise tetikleyicin hangi zaman dilimlerinde Job’ı tetiklemesidir. Basit anlamda formatı aşağıdaki gibidir. Son olarakta scheduleJob() metodunu çağıralım, parametre olarakta JobDetails ve Trigger nesnelerinin referanslarını sırası ile alır. Vereceğimiz zamanın formatı, yukarıdaki örnek için cronExpression, aşağıda detaylandırıldı.

(1) (2) (3) (4) (5) (6) (7)

1) Saniye (0-59)
2) Dakika (0-59)
3) Saat (0-23)
4) Ayın Günü (1-31)
5) Ay
6) Haftanın günü ( SUN- SAT veya 1-7)
7) Yıl (1970-2099)

Özel Karakterler
* = Herhangi bir değer.
? = Herhangi bir değer yok
- = Aralık belirtmek
/ = 3/5 (3. saniyeden sonra başlayarak her 5 saniyede bir)
, = Listeleme yapmak için
L = Son anlamına gelir, yani ayın son günü

Örnek: 0 0 6 * * Hergün saat 6 AM..
0 0 6 ? * MON Her pazartesi saat 6 AM

3/5 * 14,15,16,17 * * ? Saat 14:00 – 17:59 arasında dakikanın 3. saniyesinden sonra her 5 saniye de bir anlamına gelmektedir.

http://www.opensymphony.com/quartz/

Ref: Pro Spring Rob, Harrop and Jan Machacek

29 Nisan 2008 Salı

Tomcat 6

Tomcat 3 kavramı ifade eder.
1) Web sunucusu (EJB container’i yok)
2) Java Servletleri çalıştıran(execute) eden bir uygulama
3) JSP kütüklerini Java Servletlere dönüştüren bir uygulama

Bu anlatımızda Tomcat’in mimarisi ve dizin yapısına temel düzeyde değineceğiz. Tomcat 6, Java SE 5 üzerinde çalışan, Servlet 2.5 ve JSP 2.1 spesifikasyonlarını uygulayan bir uygulama sunucusudur. Servlet ve JSP standartlarını referans almaktadır. Bu ne anlama gelmektedir? Tomcat bu standartları yakınen takip ederek, Tomcat container’i altında çalışan her Servlet/JSP uygulaması, baska bir uygulama sunucusunda da sorunsuz çalışma imkanı verir. Bu ne işimize yarar diye bir soru sorabilirsiniz. Yazımızın girişinde de değindiğimiz gibi Tomcat web sunucusudur yani tam bir uygulama sunucusu değildir, gerekçe olarakta EJB container’in olmaması gösterilmektedir. Ama çok başarılı bir web sunucusudur. Bunu istatiksel örneklerle göstermek yerine tüm küçük ölçekli web uygulamaları veya büyük ölçekli projelerde Tomcat web sunucusunun kullanılması iyi bir örnek olacaktır. Yazılım şirketleri yaptıkları web tabanlı projelerde, projeyi yaptıkları kuruma ya da şirkete, proje teslim edilirken genelde Oracla ya da Jboss uygulama sunucularını kurarlar (bu müşteri isteğidir, daha doğrusu bunlar en başta yazılım veya donanım gereksinimlerinde yazılır) burda değinmek istediğim nokta Yazılım şirketi müşterinin hangi uygulama sunucusunu kullanacağından bağımsız olarak genelde Tomcat i kullanır, nedenleri ise Tomcat in başarılı, performansı iyi, özellikle developer’ların çalışma zamanında developer’larıda yormayacak bir web sunucusudur. Developer uygulamayı geliştirirken web sunucusunu restart etmesi, büyük bir zaman kaybı. Developer’in uygulamayı geliştirdiği makinede Oracle uygulama sunucusunun olduğunu düşünürsek hem makine için hemde developer için tam bir kabus.:)

Tomcat’in Mimarisi ve server.xml
Tomcat bir seri fonksiyonel iyi tasarlanmış bileşenlerden oluşmaktadır. Bu yapı server.xml kütüğünde tanımlanmış. Bu kütükte conf adlı alt dizinde bulunmaktadır.




Blog malesef tag yapısına izin vermemektedir. Yazıyı server.xml kütüğü ile birlikte incelerseniz daha yararlı olacağı kanısındayım.

Context
Context, Tomcat bileşenlerinin en alt bileşenidir ve Containers olarakta adlandır. Tomcat uygulanızı yüklerken(load) standart bir context oluşturmakta ve bunu konfigure etmektedir. Konfigürasyonun bir parçası da uygulamanızın WEB-INF/web.xml’de çalıştırmaktadır.


Connector
Connector TCP portunu ilişkilendiren bileşendir. Uygulama ile istemci arasındaki iletişimi sağlar. Bu iletişimi Tomcat default olarak HTTP portunu kullanarak sağlamaktadır. Bu da 8080 portudur. Uygulamanın URL’i http://localhost:8080/ diye adlandırılır. Bu portun 8080 olması zorunlu değildir, bunu değiştirebiliriz. Örneğin; port =”8090” yazarak.


Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" /
ConnectionTimeout’a set edilen 20000 değeri, session’nın 5 saat 33 dak 20 sn sonra sonlandırılacak anlamına gelmesidir.

Host
Host container’i sanal bir host sunmaktadır. Aynı sunucuda birden fazla host tanımlanabilir.

Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false"
/Host


unpackWARs =”true”, eğer WAR kütüğünü appBase dizininden silerseniz, Tomcat otomatik olarak kütüğü normal dizinine bırakır. Eğer bu false olursa uygulama direk olarak WAR kütüğünden çalıştırılacak yani çalışma zamanında daha yavaş çalışacak çünkü çalışma zamanında unzip edecek.
autoDeploy = “true” eğer uygulamayı Tomcat’in çalışma zamanında appBase dizininden silerseniz, tomcat uygulamayı otomatik deploy eder.

Engine
Container’in üst seviyesidir.Birden fazla host içerebilir ama başka bileşenin container’nı içeremez.

Engine name="Catalina" defaultHost="localhost"
Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/
Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false"
/Host
/Engine



Default Tomcat konfigürasyonu Cataline engine’ni içermektedir, default host’u ise localhost’tur.

Service
Service bileşenin amacı belirli bir engine bir ya da birden fazla connector ile ilişkilendirmek. Default Tomcat konfigürasyonu, tıpkı Cataline engine gibi, Catalina servisini içermektedir.
Service name="Catalina"


Server
Server tüm bileşenlerin üst bileşenidir. Bu bileşen bir ya da birden fazla servis içerebilir.

Listener
Listener bir Java nesnesidir. org.apache.catalina.LifecycleListener interface’ni implement etmektir. Dört tane listener’imiz var.
Birincisi Apache Portable Runtime kütüphanesini aktifleştirmektedir.
İkincisi JSP engine’i aktifleştirmektedir yani update edilen JSP kütüklerini tekrar derler(recompile).
Üçüncüsü JMX(Java Management Extensions) aktifleştirmektedir yani sistem nesnelerini yönetmeyi, remote monitoring olaylarını mümkün kılmaktadır.
Dördüncüsü global kaynakları aktifleştirmektedir yani JNDI kullanarak MySQL vb. veritabanlarına erişmeyi sağlar.

Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"
Listener className="org.apache.catalina.core.JasperListener"
Listener className= "org.apache.catalina.mbeans.ServerLifecycleListener"
Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"




Giulio Zambon ile Micheal Sekler, Beginning JSP, JSF and Tomcat Web Development kitabından alıntı yapılmıştır.

24 Nisan 2008 Perşembe

AspectJ’ ye kısa bir giriş...

AspectJ nedir? AspectJ’yi anlamak için öncelikle AOP modelini açıklamak lazım. AOP’un kısaltmasıyla başlayalım, Aspect Oriented Programming, Hacettepe Üniversitesi Bilgisayar Mühendisliğindeki arkadaşımız “Cepheye Yönelik Programlama” veya “İlgiye Yönelik Programlama” olarak çevirmiş ama bu anlatımızda kısaca AOP olarak değineceğiz. AOP, uygulamayı nesneler yerine concerns’lere (kesitlere) ayrıştırmaktadır. Java gerçek nesneye yönelik proğramlama dili ve bununla birlikte AOP tekniğini destekleyen en iyi proğramlama dilidir. AspectJ, AOP mantığını taşıyan bir Java gerçekleştirimidir.
Şimdi terimleri açıklayalım

1) Join Points (Birleşim Noktaları)
2) PointCuts (Birleşim Nokta Kümeleri)
3) Advice (Tavsiye Yordam)

AspectJ, join points kavramını aşağıdaki durumların gerçekleşmesi durumunda kullanır.
1 ) Metodu ya da yapılandırıcısını(constructor) çağırdığımız zaman.
2 ) Metodu ya da yapılandırıcısını(constructor) uyguladığımız (execute) zaman.
3 ) Herhangi bir alana (field) erişmek istedigimizde ya da güncellemek istediğimizde
4 ) Sınıfı ya da nesneyi tanımlarken
5 ) Aykırı Durumları (Exception) ele alırken

PointCuts, pointcut anahtar kelimesi ile deklare edilir. Join Points seçmek için kullanır ya da tanımlanmasını sağlar.

[visibility-modifier] pointcut name( ParameterList ) :PointcutExpr ;

Advice, PointCuts ile ilişkilendirilir ve metodu çalıştırmadan önce mi, yoksa sonra mı, kısaca metodun davranışını belirler, pointcuts lar üzerinde ne gibi işlem yapacağımıza burda karar veririz. Advice ile kullanılan terimler before Pointcuts’ın işletimine geçmeden önce ele alınmasını sağlar.after Pointcuts’ın işletimi bittikten sonra ele alınmasını sağlar.

Uygulamamızı bir örnekle açıklayalım.
package helloworld;

public aspect World {

//pointcut greeting() : execution(* Hello.sayHello(..));

//pointcut greeting() : call( * Hello.sayHello(..) );

pointcut greeting() : call( void sayHello(..) );

after() returning() : greeting() {
System.out.println(" World!");
}

before() : greeting(){
System.out.print("Asin Akdeniz...");
}

}

public class Hello {
public static void main(String[] args) {
sayHello();
}

public static void sayHello() {
System.out.print("Hello");
}
}

Burada Word AspectJ sınıfı, Hello nesnesine ait sayHello metodunun davranışına yön verir. Yani sayHello metodu çağrılmadan önce ve sonrasında bir dizi işlem yapılır. Örnekte sadece sayHello metodu çağrılmadan önce ve sonrasında ekrana bir şeyler yazmaktadır. Anlaşılır ve net bir örnek olduğu kanısındayım. Bu kodu eclipse ide’sinde deneyebilirsiniz ama oncelikle bazı plug-in’leri eklemeniz gerekmektedir. http://www.eclipse.org/aspectj/ linkinden gereken plug-in leri indirebilirsiniz.

14 Nisan 2008 Pazartesi

Bridge Pattern

Bridge örüntüsünün diğer örüntülere göre daha kompleks bir yapısı var lakin çok kullanışlı bir örüntü olduğunu deyinmeden de geçemem. Örüntümüzü örnek bir problemle ve bu probleme bakış açımızla adım adım ilerleyerek çözelim.
Daire çizmek için gereksinimiz drawCircle(x, y, r)
Çizgi çizmek için drawLine(x1, y1, x2, y2);

Bizden istenen dörtgen çizmemiz;
abstract class Rectangle {
public void draw () {
drawLine(_x1,_y1,_x2,_y1);
drawLine(_x2,_y1,_x2,_y2);
drawLine(_x2,_y2,_x1,_y2);
drawLine(_x1,_y2,_x1,_y1);
}
abstract protected void drawLine ( double x1, double y1,
double x2, double y2);
}
Bu seferde daire çizmemiz isteniyor.
abstract class Circle {
public void draw () {
drawCircle(x, y, r)
}
abstract protected void drawCircle ( double x, double y, double r);
}

Başka bir şekil istendiğinde, örneğin üçgen, yine soyut bir sınıfla tanımlamalarımızı yaparız ve onu extend eden bir sınıf yaratıp kullanırız. Fazla kötü gözükmüyor. Burda soyut sınıf kullanmadan da kodlamak mümkün. Biraz daha düşünmek gerekirse yukarıdaki örneklerden her şeklin çizimi kendi içinde. Açık kaynak proje ürettiğimizi düşünürsek başka bir yazılımcı benim yazdığım çizimlerden daha iyisini yapıyor. Bu durum herzaman mümkün daha iyisi vardır ya da daha iyisi olacak en büyük yanılgı yazdığı kodun en iyisi olduğunu düşünmektir. Daha iyisi yazılmış kodu kendi kodumuza entegre etmek bayağı zaman alacak gibi gözüküyor. Bu durumu düşünerek kodumuzu biraz daha bağımsız, modüler yapmaya çalışalım. Şekilleri ayrı, çizimleri ayrı düşünelim. Java programlama dili çoklu kalıtım desteği vermemektedir. Bizde şekil ve çizim tasarımlarımızı ayrı ayrı yapalım. Birini diğerine parametre geçirelim.

Kodu toparlayalım biraz;
abstract class Drawing{
abstract void drawLine ( double x1,double y1,double x2, double y2);
abstract void drawCircle ( double x, double y, double r);
}
class V1Drawing extends Drawing {
public void drawLine ( double x1,double y1, double x2,double y2) {
//Line kodu yazılır.
}
public void drawCircle ( double x,double y,double r) {
//Circle kodu yazılır.
}
}
abstract class Shape{
private Drawing dp;
Shape(Drawing dp;){ this.dp = dp}
abstract void draw();
public void drawLine drawLine ( double x1, double y1, double x2, double y2){
dp. drawLine(x1, y1, x2, y2);
}
public void drawCircle ( double x, double y, double r){
dp. drawCircle(x, y, r);
}
}

class Rectangle extends Shape {
public Rectangle ( Drawing dp, double x1,double y1, double x2,double y2) {
super( dp) ;
_x1= x1; _x2= x2 ;
_y1= y1; _y2= y2;
}
public void draw () {
drawLine(_x1,_y1,_x2,_y1);
drawLine(_x2,_y1,_x2,_y2);
drawLine(_x2,_y2,_x1,_y2);
drawLine(_x1,_y2,_x1,_y1);
}
}
class Circle extends Shape {
public Circle ( Drawing dp, double x,double y,double r) {
super( dp) ;
_x= x; _y= y; _r= r ;
}
public void draw () {
drawCircle(_x,_y,_r);
}
}

class Client {
public static void main(String argv[]) {
Shape r1, r2;
Drawing dp;
dp= new V1Drawing();
r1= new Rectangle(dp,1,1,2,2);
dp= new V2Drawing ();
r2= new Circle(dp,2,2,3);
r1.draw();
r2.draw();
}
}

Böylece dairemizi ve dörtgenimizi uygun bir çözümle yaratmış oluruz, az onceki problemize bir çözüm sunmuş durumdayız yani
dp= new V1Drawing();
yerine dp = new OtherDrawing(); //Bizden daha iyi kodlamış çizim sınıfını bu şekilde kendi kodumuzda çok az bir değişiklikle entegre edebiliriz.

Shape r1, r2;
Drawing dp;
dp= new V1Drawing();
r1= new Rectangle(dp,1,1,2,2);
dp= new V2Drawing ();
r2= new Circle(dp,2,2,3);
r1.draw();


Alan Shalloway, James R. Trott , Software Patterns Series kitabından alıntı yapılmıştır.

Facade Pattern

Nedir facade örüntüsü? Nerde ihtiyaç duyarım, nasıl kullanırım? Facede örüntüsü alt sistemin arayüzlerini kontol altına almaya çalışan birleşik bir arayüz(interface) sunmaktadır. Daha açıklayıcı olmak gerekirse yapılmış bir sistemin yapısını bozmadan, alt sistemlerin arayüzlerini kullanarak daha derli toplu bir arayüz sunmak ve bizim bu alt sistemi daha iyi, aktif ve doğru kullanmamıza olanak sunmak.
Terimlerimiz:
Amaç: Var olan sistemi daha basit bir şekilde nasıl kullanırım.
Problem: Kompleks bir sistemi daha akıcı ve sade nasıl yapabilirim.
Çözüm: Facade örüntüsünün çözüm sunduğu bir arayüz tasarlayıp alt sistem kaynaklarını istemciye tek elden erişilebilir bir hale getirmek.

Alan Shalloway, James R. Trott , Software Patterns Series

Şekil 2
Şekil2 de iki tane istemcinin(client) var olan bir sistemin kaynaklarını kullanmasını goruyoruz. Burda beliren sorun da tüm çıplaklığı ile gözüküyor. İstemcinin birden fazla alt sisteme erişmesi, kopleks yapının oluşmasına neden oluyor. Modelleme de bile karmaşıklık göze çarpıyor, bu işin kodlama aşamasını düşünmek ürkütücü geliyor. Bu yazıyı okuyan arkadaşların belki facade gerek olmadığını düşünüyorsa,
1) Sistemin birden çok alt sistemden oluştuğunu düşünürsek
Sorun: Aynı sürecin birden fazla programcı tarafında yapılması yani aynı kodun büyük bir projede tekrarlanıp durması.
XX adlı Muhendisinin kodu
A kaynağına eriş
A dan doneni B kaynağına yolla
B den doneni C ye yolla ve dönen değeri kullan.

YY adlı Muhendisinin kodu
A kaynağına eriş
A dan doneni B kaynağına yolla
B den doneni C ye yolla ve dönen değeri kullan.

2) İki mühendisin aynı yetkinlikte olmaması.
Sorun : Kaynakların doğru ve etkin kullanılmaması.
Bunu da unutmamak lazım: Yazdığınız kodun sizden sonraki mühendis tarafından okunabilir olması ve taktirle karşılanması mühendislik etiği kavramlarını oluşturmaktadır

Singleton Pattern

Singleton Örüntüsünde amacımız sınıfımıza ait sadece bir tane nesne yaratmak ve bu sınıfa erişmek istediğimizde bize aynı nesnenin refaransını döndermesidir.

Anahtar Sözcükler:
Amaç: Sadece bir tane nesne yaratmak ve nesne global tanımlanmayacak.
Problem:Birden fazla istemcinin bir sınıfa ait nesneye ihtiyaç duyması durumunda, dikkat edilmesi gereken istenen sınıfa ait birden fazla nesne yaratmamak.
Çözüm : Sadece bir nesne yaratmayı garanti etmek.
Kodlarken:
1) İstenen sınıfın üyesini static ve private tanımlamak ve başlangıçta ki değerine NULL atamak.
2) Constructor’ı protected ve private belirtmek.

Burda dikkat edilmesi gereken durumlardan biride sınıfa ait nesneyi yaratırken iki farklı istemcinin aynı anda sınıfı yaratan methoda erişmesidir. Burada çoklu thread’den bahsediyoruz. İki thread’in, sınıfı yaratan metoda aynı anda erişmesi, sınıda ait nesnenin yaratılmadığını varsayarsak, aynı anda ikisinin sınıfa ait nesneyi yaratmaya çalışması sıkıntıya neden olacaktır, bu nedenle yapacağımız Java örneğinde synchronized kullanacağız, bu da ikili kitlemeyi engelleyecek. İlk görev senkronize’ye girdi mi diğer görevler ilk görevin çıkmasını beklemek zorundadır, bu da kilitlenme sorununu çözer.

//wikipedia J Java5
public class Singleton {
private static volatile Singleton INSTANCE = null;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null)
synchronized(Singleton.class) {
if (INSTANCE == null)
INSTANCE = new Singleton();
}
return INSTANCE; }
}

24 Mart 2008 Pazartesi

Template Method Pattern

Template Method Örüntüsünü(Pattern) bildigim kadarı ile örnekleyerek açıklayacam.
VT bağımsızlığını ele alan bir framework geliştireceğimi varsayımı altında , yapının Oracle, MS SQL ve diğer VT lerini destekleyeceğini dusunelim. Yapmamız gerekenler...
1. sürücüleri yükleme
2. iletişimi sağlama (send connection)
3. sorguyu çalıştırmak
4. dataset i oluşturma

Amaç,
1) alt sınıflara süper sınıfın davranışlarını aktarmak
2) duplication kodu engellemek
3) alt sınıfın davranışını kontrol etmek

Buradaki asıl özgürlük abstract metodu override eden subclass ların bu metodları implement ediş biçimidir, yani aynı işi farklı farklı yöntemlerle çözümü mevcut örneğin bu örneği düşünürsek her VT nin sorguları optimize etme şekli farklıdır. Bizi ilgilendiren nasıl yaptığı değil nasıl kullanacağımızdır. Özgürlükten bahsettik işte bu özgürlük büyük güç katmaktadır.

public abstract class CommanVT {
protected Connection connection;

abstract void driverYukle();
abstract Connection getConnection(String url, String userId, String password);
abstract Object executeQuery(String query);

final void doQuery(String url, String userId, String password, String query,
Object obj){
driverYukle();
setConnection(url, userId, password);
//Query’i SQL’e donusturmek ve optimize etmek için yazılan kod
//Gerekli kodlamalar burda yapılmakta Query baska bir
//syntax la yazılmış varsayımı altında...
obj = executeQuery(query);
}

}

public class Oracle extends CommanVT{
@Override
void driverYukle() {
System.out.println("Oracle Driver Load");
}
@Override
void setConnection(String url, String userId, String password) {
System.out.println("Oracle connection");
}
@Override
Object executeQuery(String query) {
System.out.println("Oracle execute Query");
}
}

public class PostgreSQL extends CommanVT{
@Override
void driverYukle() {
System.out.println("PostgreSQL load");
}
@Override
void setConnection(String url, String userId, String password) {
System.out.println("PostgreSQL connection");
}
@Override
Object executeQuery(String query) {
System.out.println("PostgreSQL execute");
}

}

JavaScript

JavaScript gerçek adıyla LiveScript, Netscape mühendislerinden Brenden Eich tarafında 1995 yılında geliştirilmiştir.Birden çok platformda ve donanım bağımsız çalışmaktadır. HTML’ ye entegre edilmekte ve statik yapıyı dinamiğe dönüştürmeye yardımcı olmaktadır.

JavaScript’in adında da geçen Java kelimesine aldanmamak gerekir, JavaScript Java degildir. Java Sun Microsystems tarafından geliştirildi, JavaScript ise Netscape tarafından geliştirildi. JavaScript web sayfalarına gömülmektedir ve web browser’da çalışmalıdır. Java kodları derlenmektedir aksine Javascript kodları JavaScript engine’i tarafından yorumlanmaktadır.

JavaScript dili nesne tabanlıdır ama kesin olarak nesne ilişkili değildir, yani miras (inheritance), sınıf (class) kavramları yoktur. JavaScript uygulamalara gömülen tek script dili degildir, örneğin VBScript, Microsoft tarafından geliştirilen JavaScript gibi bir script dilidir fakat sadece Microsoft Internet Explorer tarafından çalıştırılmaktadır.

JavaScript’in temel kavramlarını anlatmadan biraz daha ileri seviyede geliştirilen aşağıdaki kodu incelemeniz JavaScriptle neler yapabileceginizi daha net gorebilmenize yardımcı olacağı kanısındayım. Aşağıda yazılan kodu JavaScript olmadan da, HTML dili ile de kodlayabilirsiniz ama sayfanızda dinamik olarak bir table’e satır ve eklenen satıra sütün eklemek, eklenen sütünlara textfield, button, checkbox yerleştirmek için JavaScript’e ihtiyaç duyacaksınız yani geliştirilen örnek size yardımcı olacaktır.

//maalesef blog html tag lerine izin vermemektedir, kodu oldugu gibi bırakamadım
//html ve body tag ı açılacak
//script tag ı açılacak
function controlSelect(kaynak, hedef){
if(kaynak.checked == true){
hedef.style.visibility = 'visible';
}
else if(kaynak.checked == false){
hedef.style.visibility = 'hidden';
}
}
function doIt(obj){
label.value = obj.value;
}
function changeImage(obj,url){
obj.src = url;
}

//script tag ı kapatılacak
//id si 'deneme' olan bir table açılacak
//script açılacak

var table2 = document.getElementById('deneme');
table2.style.cssText = "cellspacing: 0; cellpadding : 0 ; border:2; width: 400; height: 200";

var tableRow = table2.insertRow(0);
tableRow.style.cssText = 'background-color:red; width:200px; height:200px';

var tableRow2 = table2.insertRow(1);
tableRow2.style.cssText = 'background-color:blue; width:200px; height:200px';

var rowTd = document.createElement('TD');
var rowTd2 = document.createElement('TD');

var img = document.createElement('img');
img.src = 'folder.gif';
img.onmouseover = function() {changeImage(img,"base.gif")};
img.onmouseout = function() {changeImage(img, "folder.gif")};

var textEx = document.createElement('INPUT');
textEx.type = 'TEXT';
textEx.name = 'name';
textEx.size = '15';

var buttonEx = document.createElement('INPUT');
buttonEx.type = 'BUTTON';
buttonEx.value = 'Goster'
buttonEx.size = '5';
buttonEx.onclick = function() {doIt(textEx)};

var label = document.createElement('INPUT');
label.readOnly = 'true';
label.style.cssText = 'background-color:red';

var selectEx = document.createElement('SELECT');
selectEx.name = 'select';
selectEx.options.add(new Option('asin','1'));
selectEx.options.add(new Option('ersin','2'));
selectEx.options.add(new Option('dery','3'));
selectEx.style.visibility = 'hidden';

var checkEx = document.createElement('INPUT');
checkEx.type = 'CHECKBOX';
checkEx.name = 'check';
checkEx.onclick = function() {controlSelect(checkEx,selectEx)};

rowTd.appendChild(img);
rowTd.appendChild(textEx);
rowTd.appendChild(buttonEx);
rowTd.appendChild(label);
rowTd2.appendChild(checkEx);
rowTd2.appendChild(selectEx);

tableRow.appendChild(rowTd);
tableRow2.appendChild(rowTd2);

//script tag'ı kapatılacak
//table,body html tag'ı kapatılacak

20 Mart 2008 Perşembe

Prototype Pattern

Bir sınıftan birden fazla nesne yaratma ihtiyacı duyarız fakat bu işlem hız ve bellek yönetimi açısından maliyetli bir iştir. Bunun yerine o nesnenin orjinal kopyasını yapmak bize önemli ölçüde kazanç sağlayacaktır. Burada “new” operatörü yerine clone() methodu kullanılır. Bu metodu kullanırken dikkat etmemiz gereken hususlar ya da avantajları ve dezavantajlarını da belirtelim.

1) private alanlar direkt olarak atanmaz yani setter ve getter alanlara ihtiyaç duymaktadır, bu da fazla kod maliyeti olarak görülmektedir.//Dezavantaj
2) clone() metodu nesnenin bellekteki alanını bir işlemde kopyalamaktadır. Bu da nesneyi yaratmaya gore çok daha hızlıdır.

x.clone() != x // bu ifade doğru; aynı referans id lerine sahip değiller.
x.clone().getClass() == x.getClass() // bu ifade doğru; aynı sınıfın farklı id lerde.

Person adında bir sınıfımız olsun, bu sınıfın adı, soyadı alanları olsun. Person sınıfını yaratalım ve alanlarına atama yapalım.

Person person = new Person();
person.setName(“Asin”);
person.setSurname(“Akdeniz”);

yaratıp atamaları yaptıktan sonra clone lama işlemine geçelim.

Person person2 = person.clone();

System.out.println(“Name:”+person2.getName());
System.out.println(“Surname:”+person2.getSurname());

Beklenen Çıktı,
Name : Asin
Surname: Akdeniz

Devam edelim,
person2.setName(“Ersin”);

System.out.println(“Name:”+person2.getName());
System.out.println(“Name:”+person.getName());
Beklenen Çıktı,
Name: Ersin
Name : Asin

Sonuç olarak clone() lama ile referans atamıyoruz, bunu clone() lanmış nesnemizin alanlarını değiştirince orjinal nesnemizin durumuna yansımaması ile daha net gorebiliyoruz. Aşağıdaki ifadeyi incelerseniz arasındaki farkı daha net gorebilirsiniz.

Person person = new Person();
Person person2 = person;

Yukarıdaki ifadede ilk satırda bir Person sınıfına ait bir nesne yaratılmıştır.İkinci satırda ise oluşturmuş olduğumuz bu nesneye bir referans vardır yani oluşturulan bu nesneye ulaşırken person2 ya da person yazarak ulaşabiliriz.

clone() metodunun kullanılması için
• Clonable interface nin implement edilmesi lazım.
• Nesne clone’lanmayınca CloneNotSupported Exception fırlatır.

public class Person implements Cloneable{
private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public static Person getPerson(Person person){
try {
return (Person) person.clone();
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Person.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}

public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setName("Asin");

Person perClone = Person.getPerson(person);
System.out.println("Name:"+perClone.getName());
perClone.setName("Ersin");
System.out.println("Person Name:"+person.getName());
System.out.println("Person (Clone) Name:"+perClone.getName());
System.out.println(perClone);
System.out.println(person);
}

}
Beklenen Çıktılar...
Name:Asin
Person Name:Asin
Person Clone Name:Ersin
clonejavs.Person@12dacd1
clonejavs.Person@1ad086a

14 Mart 2008 Cuma

J2ME

J2ME programlama dili ile ilgili giriş düzeyinde faydalı olacağına inandığım kendi yazdığım yazının linki

http://belgeler.cs.hacettepe.edu.tr/yayinlar/eski/J2ME.pdf