SİTE
İÇİ ARAMA |
|
Blogroll |
|
|
|
Java ile Model View Controller Yapısı (MVC) |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu
makalede sizlere yazılım denilince akla ilk gelen nesne tabanlı programlama
(OOP) konusunda bize çok yardımcı olacak olan bir yapıya değineceğim.
Yazılımla, programlama ile uğraşan herkesin aşina olduğu bir sözdür OOP.Bir programlama dili öğrenmeye çalıştığımızda sürekli olarak yazılımla uğraşmış olan
veya çalışmaya devam eden tanıdıklarımıza ben A dilini öğrenmek istiyorum sizce iyi mi, başkası B dilini öğrenmek istiyorum iyi mi diye sorular sormaktan
kendimizi alıkoyamıyoruz.Her ne kadar bize verilen bilgiler bizim düşüncemizden farklı olsa bile yapacağımızdan da vazgeçeceğimizden değil sadece bir kişi bile
bana destek versin arayışından kaynaklanan bir durum oluyor.
Sorularımızın sonucunda onlarda dil saydığımız halde ortak bir yanıt oluyor.Sizce bir dil ismimi hayır.Cevap ise şu.Herkes bir programla dilini öğrenebilir ve
birşeyler yapabilir.Fakat yapabileceklerini senin dışında başkalarınında anlaması gerektiğini ve bunun iş yaşamından diğer bütün yaşamına kadar devam edecek bir durum
olduğunu unutmaman gerekiyor diye bir cevap alıyoruz ve devamında ise.İşte bu sürekliliği, anlaşılırlığı sağlayacağın en önemli mantık belirli nesneler ile
çalışman olacaktır.Bu nesne yapılarınıda nesne tabanlı programlar ile sağlayabilieceğini unutma diye ekliyor.Daha sonra ise nesne tabanlı programlar dediğimiz
zaman aklına şu bir dil benim yerime bütün karmaşılığı ortadan kaldırabiliyor.Hayır öyle değil.Bunu için gerekli olan Model View Controller
adı verilen bir teknoloji yardımcı olabilecektir.Şimdi bu bilgiler ışığında Model View Controller ı biraz daha yakından tanıyalım.
MVC nin temel çalışma prensibi...
MVC nin asıl çalışma prensibi projemizde kullandığımız yapıları katmanlamak.Veri tabanı için bir katman,Sorgularımız için ayro bir katman ve son olarak
son kullanıcıya sunulacak olan ekran için ise ayrı bir katman oluşturmaktır.
Fakat bu mantığı bilmeyen yazılımcılar tarafından oluşturulan projeleri düşünürsek;bir web uygulamasını ele alalım.Html kodları arasında veri tabanımıza
bağlanabilmemiz için gerekli olan connectionlar, eğer veri tabanımızdan herhangi bir isteğimiz var ise sorgular bunlar ile de yetinmeyip bir de sayfalar
arası aktarım yapmak istiyorsak bu da *.HTML sayfamızın içerisinde bulunacak.Yeni başlayan yazılımcılara bu yaptıkları uygulamaların yanlış olduğunu ve sizin dışında
başka kişilerin uygulamanı geliştirmek istediğinde anlayamayacaklarını daha sonra sende annlayamayacaksın diye söylemeye çalışıyorum.Fakat neresi karmaşık ki
çok rahatlıkla anlaşılabiliyor şeklinde cevaplar alabiliyorum.Ama şu aklımızda daima kalmalıdır ki.Bi proje ile uğraşırken aklımız genellikle onun üzerinde
yorduğumuz için hata satırını bile aklımızda tutabilmekteyiz.Fakat proje bittikten sonra ve uygulamaya geçildikten sonra yaklaşık bir ay içerisinde neler
yapıtığımızı unutmaya başlıyoruz.İşte en kötü yanı burada başlıyor.Herhangi bir yerinde düzeltme istendiğinde ne yaptığımızı biz dahi anlamakta zorluk çekebiliyoruz ve
bu uygulamaların kalıp biçiminde gözükmesi için arayışlar içerine giriyoruz.Karşımıza çıkan yapı Model View Controller oluyor.
Bu isimlerin anlamlarına değinmek gerekirse;
Model
Model genellikle veri tabanı işlemlerimizi yani işlerimizi( business ) yaptığımız yapıdır.Veri tabanımız üzerinde yapılabilecek sorgularımızı burada belirler ve
controller ı atamamızı sağlarız.Bu sayede veri tabanımıza dışarıdan daha kolay erişebilir ve çeşitli metodlarla daha kolay idare/müdahale edilebilir hale getirir.
Ufak bir örnek kod ile de örneklemek gerekirse;
public class ProjeSahip {
-------
-------
-------
private String name;
private String dep;
private String cont;
private String kayit;
private String aciklama;
public String getAciklama() {
return aciklama;
}
public void setAciklama(String aciklama) {
this.aciklama = aciklama;
}
public String getAdminUserName() {
return adminUserName;
}
public void setAdminUserName(String adminUserName) {
this.adminUserName = adminUserName;
}
------
------
------
}
|
Veritabanı tablomuzda olan sütunlar yardımıyla oluşturulmuş olan değişkenler Model ve Controller da kod bloğunda
kullanılmak üzere oluşturulmuş değişkenlerdir.
public class ProjeSahipDao {
//AssignProjectServlet Controller olarak kullanılacak class
public ProjeSahip insertProjeSahip(ProjeSahip projeSahip)throws Exception{
Connection conn=null;
PreparedStatement pstmt=null;
String sqlStr="INSERT INTO ZZZ_PROJESAHIP(PS_ID,P_ID,STAJUSERNAME,ADMINUSERNAME,SDURDEG,DURUM,PBAS,PBIT,D_ID,PBITIS)";
sqlStr+="VALUES (?,?,?,?,?,?,?,?,?,?)";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@10....:1...:KO...", "stajer", "stajer");
pstmt = conn.prepareStatement(sqlStr);
pstmt.setInt(1, projeSahip.getPsId());
pstmt.setString(2, projeSahip.getPId());
pstmt.setString(3, projeSahip.getStajUserName());
pstmt.setObject(4, projeSahip.getAdminUserNameLogged());
pstmt.setString(5, projeSahip.getSDurDeg());
pstmt.setString(6, projeSahip.getDurum());
pstmt.setString(7, projeSahip.getPBas());
pstmt.setString(8, projeSahip.getPBit());
pstmt.setString(9, projeSahip.getDId());
pstmt.setString(10, projeSahip.getPBitis());
pstmt.executeUpdate();
} catch (Exception e) {
throw e;
}
finally{
try {pstmt.close();} catch (Exception e) {}
try {conn.close();} catch (Exception e) {}
}
return projeSahip;
}
//ChangeAssignmentInfoServlet Controller olarak kullanılacak class
public ProjeSahip updateProjeSahipChangeAssignInfo(ProjeSahip projeSahip)throws Exception{
Connection conn=null;
PreparedStatement pstmt=null;
try {
//PS_ID radiobutondan HIDDEN olarak alinacaktir.
String sqlStr="UPDATE ZZZ_PROJESAHIP SET STAJUSERNAME=?,PBIT=? WHERE PS_ID=?";
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@10....:1...:KO...", "stajer", "stajer");
pstmt = conn.prepareStatement(sqlStr);
pstmt.setString(1, projeSahip.getStajUserName());
pstmt.setString(2, projeSahip.getPBit());
pstmt.setInt(3, projeSahip.getPsId());
pstmt.executeUpdate();
} catch (Exception e) {
throw e;
}
finally{
try {pstmt.close();} catch (Exception e) {}
try {conn.close();} catch (Exception e) {}
}
return projeSahip;
}
|
Veri
tabanında ki değişkenleri tanımladığımız classtan yararlanarak controller
da kullanılmak üzere değişkenlerimizi oluşturduk.
Çok önemli not 1:Web
üzerinden çalışan uygulamalarda hatalarınızı en iyi şekilde anlayabilmeniz için
Exception kullanmanızı şiddetle öneriyorum.Çünkü oluşacak hataları
programcıların dışında kullanıcılarda görecek ve belki bizler için bir anlam
taşıyan fakat kullanıcılar için herhangi bir anlam taşımayan server hatalarını
göstermemek içinde çok yararlı olacaktır.Ayrıca binlerce satır kodun arasında
yanlış bir parantez yüzünden yanlış çalışan uygulamamızın sorununu anlamamız
belki haftalar alırken Exception lar yardımıyla o an alayabilme
şansımız vardır.Kısacası bir Web üzerinden çalışan uygulamalar geliştiriyorsanız
muhakkak Exception kullanmanızı öneriyorum. Exception Handling
ile daha ayrıntılı bilgi için Burak Selim Şenyurt un Kendi
İstisna Nesnelerimizi Kullanmak isimli makalesini inceleyebilirsiniz.
Çok önemli not 2:Veri
tabanımıza ulaşabilmek için açmış olduğumuz connection (bağlantı) ları sağlıklı
bir şekilde kapatabilmemiz için gerekli olan kod yapılarını Finally
bloğu içerisinde bulunması gerekmektedir.Genellikle kullanıcıların
yaptığı ortak hata oluşturduğumuz try bloğunun sonuna yerleştirmek
oluyor.Fakat bu thread mantığı ile işleyen işletim sistemlerimizde yanlış sonuçlar
oluşmasına yol açmaktadır.Ayrıca Exception(hata) alan kod parçacıkları hata
aldığı yerde kod bloğundan atlar ve bir sonraki kod bloğuna girer.Fakat yanlış
anlaşılmaması gereken bir nokta var,hata alındığı zaman nasıl olsa bir sonraki
blok olan catch bloğuna girer ve burda da istediğim sonuca
ulaşırım denilebilir.Fakat hata aldığı catch bloğundan sonra ki bloğu maalesef
kontrol edilmemektedir.Onun yerine Finally bloğu varsa onu
kontrol edim yoksa olduğu gibi sonuçlandırayım mantığı ile çalışmaktadır derleyicilerimiz.Bunun
sonucunda da açık kalan bağlantılarımızın fazlalığı sonucunda aşırı yüklenmeden
dolayı maksimum kullanıcı hatası alabiliriz.İşte bu istenmeyen durumun engellenmesi
için oluşturduğumuz bağlantıların sağlıklı bir biçimde kapatılabilmesi için
daima Finally bloğunu kullanmanızı öneriyorum.
Controller
Model yardımıyla oluşturduğumuz sorguların kullanıcı tarafından alınan veriler
ile birleşip uyumlu bir biçimde çalışmasını sağlayan yapıdır.En genel tanımı
Uygulamaya gelen sorgulara karşı nasıl cevap verilmesi gerektiği konusunda planı
yapan, hareketi planlayan bölümüdür.
MVC den controller yardımı ile oluşturulmuş class ile ilgili bir örnek vermek
gerekirse;
İlk olarak içerisinde herhangi bir sorgu ile ilgili işlem yapılmayan tamamiyle
oluştuduğumuz classlar arasında dolaşmamızı sağlayan bir controller örneği
olacak.
public class InternSearchServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getParameter("Search")!=null){
RequestDispatcher rd= request.getRequestDispatcher("EditInternersPage.jsp");
rd.forward(request, response);
}
else if (request.getParameter("Cancel")!=null){
response.sendRedirect("EditInternersPage.jsp");
}
}
}
|
Bu class ın özelliği tamamiyle kullanıcıdan
gelen isteklere göre gereken sayfaları kullanıcılara sunmak.
Controller ile ilgili ikinci örneğimiz ise istek ile aktarmaya ek olarak kullanıcının
yaptığı işlemleri oluşturmuş olduğumuz model e aktararak gerekli sorgunun yapılması
ve bunun sonucunu view e taşıması yani kullanıcıya sunması olacaktır.
public class ProjectAssessmentServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getParameter("MainPage")!=null){
response.sendRedirect("AdminMainPage.jsp");
}
else if(request.getParameter("Submit")!=null){
try {
ProjeDegerlendirme bean=new ProjeDegerlendirme();
ProjeDegerlendirmeDao dao=new ProjeDegerlendirmeDao();
bean.setDurum(request.getParameter("Result"));
bean.setAciklama(request.getParameter("Comments"));
bean.setDId(request.getParameter("RadioButton"));
dao.updateAssign(bean);
} catch (Exception e) {
e.printStackTrace();
}
response.sendRedirect("ProjectAssessmentPage.jsp");
}
}
}
|
Kullanıcıdan gelen istekleri oluşturulmuş olan sql sorgularına taşıyor ve aldığı sonuçları ilgili web sayfasına
aktarmaktadır.
View
Bu bölüm kullanıcıya cevap olarak döndürülen arayüzdeki statik ya da dinamik bileşenleri (html,jsp,css,...) barındırır.Diğer yardımcı yapılar yardımıyla
programcılara da oldukça anlaşılır ve tamamiyle sayfa üzerinde kullanıcıya gösterilen form araçlarının bulunduğu kod parçası kalır.
Artık ilk başta çok karmaşık bir yapı içerisinde diye hasta raporu verdiğimiz ve yukarıda ki yapıların hepsini bünyesinden barındıran a.*jsp sayfamıza
bakalım ne kadar karmaşık!!! kod parçacıkları kalmış.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%if ( request.getSession().getAttribute("Login")==null ){%>
<jsp:forward page="ErrorPage.jsp"/> <% }%>
<%if ( !request.getSession().getAttribute("isAdmin").toString().equals("true") ){%>
<jsp:forward page="ErrorPage2.jsp"/> <% }%>
<html>
<head>
<script language="JavaScript" src="C:\workspace\mayhem\src\IdentityControl.js">
</script>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript">
function duplicateUserName(){
if(<%=request.getSession().getAttribute("duplicateuser")%> ){
document.myform.AdminName.value=<%=request.getSession().getAttribute("AdminName")%>;
document.myform.AdminSurName.value=<%=request.getSession().getAttribute("AdminSurName")%>;
document.myform.AdminSecondName.value=<%=request.getSession().getAttribute("AdminSecondName")%>;
document.myform.AdminIdentityNumber.value=<%=request.getSession().getAttribute("AdminIdentityNumber")%>;
document.myform.AdminDepartment.value=<%=request.getSession().getAttribute("AdminDepartment")%>;
alert("Kullanici ismi zaten kullaniliyor!!");
return false;
}
else {
return true
}
}
</script>
</head>
<body onload="duplicateUserName()">
<SCRIPT LANGUAGE="JavaScript">
function validation(){
formObj=document.myform
if ((formObj.AdminUserName.value == "")||(formObj.AdminPassword.value == "")) {
alert("Kullanıcı adınızı ve şifrenizi giriniz ");
return false;
}
else {
return true;
}
}
</SCRIPT>
<P> </P>
<BLOCKQUOTE>
<form ACTION="NewAdminRecordServlet"METHOD="get" name="myform">
<BLOCKQUOTE>
<P>UserName:
<input type="text" name="AdminUserName" maxlength="10"/>
</P>
<P>Password:
<input type="password" name="AdminPassword" maxlength="8"/>
</P>
<hr/>
<P>Name:
<input type="text" name="AdminName" maxlength="10"/>
</P>
<P>Surname:
<input type="text" name="AdminSurName" maxlength="15"/>
</P>
<P>Second Name:
<input type="text" name="AdminSecondName" maxlength="10"/>
</P>
<P>T.C. Identity Number:
<input type="text" name="AdminIdentityNumber" onclick="value=""" onkeyup="karakterfiltre(this);" maxlength="11" size="11"/>
</P>
<P>Department:
<select name="AdminDepartment" size="1">
<option value="Bilgi Sistemleri">Bilgi Sistemleri</option>
<option value="Insan Kaynaklari">Insan Kaynaklari</option>
<option value="Kargo Operasyonlari">Kargo Operasyonlari</option>
<option value="Mali ve Idari Isler">Mali ve Idari Isler</option>
<option value="Satis Pazarlama">Satis Pazarlama</option>
<option value="Yonetim Raporlama">Yonetim Raporlama</option>
</select>
</P>
<P> </P>
</BLOCKQUOTE
<input type="submit" value="Submit"name="Submit" onClick="return validation()"/>
<input type="reset" value="Reset"name="Reset"/>
<input type="submit" value="Cancel" name="Cancel"/>
</form>
<P>
<SCRIPT>
</SCRIPT>
</P>
</BLOCKQUOTE>
</body>
</html>
|
Model View Controller yardımı ile karmaşık görünecek bir yapının ne kadar basitleştiğini ve sadece bizim tarafımızdan değil, yerimize devam edecek
kişiler için bile çok rahat kullanılabilecek ve anlaşılır olabilecek bir yapı bırakmış oluruz.
Unutulmaması gereken bir durumda vardır ki, yazının başında da bahsettiğim gibi bir proje yapılıp teslim edildikten sonra tamamen herşeyinin bitmiş
olduğu anlamına gelmemektedir.Zamana bağlı olarak oluşacak olan hataların düzeltilmesi gerekecektir.Bu işlemim kolay bir biçimde yapılabilmesi için ise
oluşturduğumuz programın kodların okunabilirliğinin en üst düzeyde, oluşturduğumuz nesnesel yapıların da kullanılabilme olanağı olması gerekmektedir.Tersi
bir durum olması durumunda kısa sürede yapabileceğimizi bir işi çok uzun zamanlarda yapmak durumunda kalabiliriz.
Oluşturduğumuz programların ilk olarak nasıl en çabuk şekilde çalıştırabilirim ve elimden çıkarabilirim mantığı yerine bana verilen süre içerisinde nasıl en
verimli olabilecek gelecekte yazmış olan kişinin bile aklında karmaşıklık çıkarmayacak düzende olmasına önem gösterilmeli.Unutulmamalıdır ki sıkı bir çalışma
ile herkes iyi programcı olabilmektedir.Fakat iyinin ötesinde aranan mükemmel bir programcı olabilmemiz için OOP mantığını MVC mantığını ve bunun gibi oluşturduğumuz
yazılımları sürekli kılabilecek yapıları çok iyi bir şekilde kavramamız gerekmektedir.
Değinmek istediğim başka bir konu daha var.Verdiğim kod örneklerinin java kodları olduğu dikkatinizi çekmiştir sanırım.Bu oluşturduğumuz yapı çok temel bir
konudur ve bu yapı en çok Java ile kullanılmaktadır. .net ise arka planda bu yapıyı uygulamaktadır.Gerçek anlamda MVC kullanabilmemiz için java gibi c++ gibi
temel dilleri inceleyip bu inlemelerin sonucunda .net ile gerçek anlamda MVC kullanmaya başlıyorduk.Fakat bazılarımızda bu mantığı kafalarında oluşturmuş.Bu
veritabanın ayrı bir sınıfta kalması gerektiğini, kontrol için ayrı bir sınıf olması gerektiğini ve kullanıcıya sunacağım ekranda form üzerinde ki yapılar dışında
bir kod olmaması gerektiğini düşünüp oluşturabiliyorlar.Bu durum gerçekten çok iyi bir mantık oluyor.Fakat her ne olursa olsun teorik olarak araştırılıp
incelenmesi gereken bir durumdur.
Sonuç olarak anlattıklarımız toparlamak gerekirse,oluşturduğumuz uygulamarın sürekliliği, anlaşılabilirliği için oluşturduğumuz kodları daha dikkatli oluşturmalı
ve yaptıklarımızı geleceğimizi düşünerek yapmalıyız.Bu yapacaklarımız bizleri vasat üstü yazılımcılar yerine parmakla gösterilen aranan insanlar durumuna
getirecek.Bence kullanırken yazılım ile ilgili bir meslekte uğraşıcaksak aklımıza gelen ilk şey bu olmalıdır.
Umarım yararlı olmuştur.
MVC ile ilgili bilgilerimi yenilememi ve daha ayrıntılı bilgiler edinmemi sağlayan Akın ERKAYA ya teşekkürlerimi bir borç bilirim.
Daha iyi ve anlaşılır uygulamalar geliştirebilmeniz dileğiyle.
İyi çalışmalar
Turhal TEMİZER
Makale:
Java ile Model View Controller Yapısı (MVC) J# ve Java dili Turhal Temizer
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|
|