Java tabanlı web uygulama mimarilerini paylaşalım!
Java kullanılarak uygulanacak web uygulamaları için çok sayıda farklı mimari vardır. Bu sorunun cevapları, artıları ve eksileri ile çeşitli web uygulama tasarımlarının bir kütüphanesi olarak hizmet edebilir. Cevapların öznel olacağını anlarken, olabildiğince objektif olmaya ve listelediğimiz artıları ve eksileri motive etmeye çalışalım.
Mimarinizi tanımlamak için tercih ettiğiniz ayrıntı düzeyini kullanın. Cevabınızın herhangi bir değere sahip olması için, en azından tanımladığınız mimaride kullanılan başlıca teknolojileri ve fikirleri tanımlamanız gerekecek. Ve son olarak , mimarinizi ne zaman kullanmalıyız?
Başlayacağım ...
Mimariye genel bakış
Java EE, Java Persistence API, Servlet ve Java Server Pages gibi Sun'ın açık standartlarına dayalı 3 katmanlı bir mimari kullanıyoruz.
- Kalıcılık
- İş
- Sunum
Katmanlar arasındaki olası iletişim akışları şu şekilde temsil edilir:
Persistence <-> Business <-> Presentation
Bu, örneğin sunum katmanının hiçbir zaman kalıcılık işlemlerini çağırmadığı veya gerçekleştirmediği anlamına gelir, bunu her zaman iş katmanı aracılığıyla yapar. Bu mimari, yüksek kullanılabilirliğe sahip bir web uygulamasının taleplerini karşılamaya yöneliktir.
Kalıcılık
Oluşturma, okuma, güncelleme ve silme ( CRUD ) kalıcılık işlemlerini gerçekleştirir. Bizim durumumuzda ( Java Persistence API ) JPA kullanıyoruz ve şu anda kalıcılık sağlayıcımız olarak Hibernate kullanıyoruz ve EntityManager'ı kullanıyoruz .
Bu katman, her bir sınıfın belirli türden varlıklarla uğraştığı (yani bir alışveriş sepetiyle ilgili varlıklar tek bir kalıcılık sınıfı tarafından ele alınabilir) ve bir ve yalnızca bir yönetici tarafından kullanıldığı birden çok sınıfa bölünmüştür .
Ek olarak, bu katman aynı zamanda , vb. Şeyler olan JPA varlıklarını da depolar .Account
ShoppingCart
İş
Web uygulaması işlevselliğine bağlı tüm mantık bu katmanda yer alır. Bu işlevsellik, bir ürün için kredi kartını kullanarak çevrimiçi ödeme yapmak isteyen bir müşteri için bir para transferi başlatıyor olabilir. Web tabanlı bir oyunda yeni bir kullanıcı oluşturmak, bir kullanıcıyı silmek veya bir savaşın sonucunu hesaplamak da olabilir.
Bu katman, birden çok sınıfa bölünmüştür ve bu sınıfların her biri, Stateless Session Bean (SLSB) @Stateless
haline gelmek için notlandırılmıştır. Her SLSB'ye yönetici adı verilir ve örneğin bir yönetici , adı verildiği gibi açıklamalı bir sınıf olabilir .AccountManager
Tüm AccountManager
ihtiyaç CRUD işlemleri gerçekleştirmek için bu örneğine uygun çağrılar AccountManagerPersistence
kalıcılık katmanındaki bir sınıftır. İki yöntemin kaba bir taslağı şunlar AccountManager
olabilir:
...
public void makeExpiredAccountsInactive() {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
// Calls persistence layer
List<Account> expiredAccounts = amp.getAllExpiredAccounts();
for(Account account : expiredAccounts) {
this.makeAccountInactive(account)
}
}
public void makeAccountInactive(Account account) {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
account.deactivate();
amp.storeUpdatedAccount(account); // Calls persistence layer
}
Biz kullanmak konteyner yöneticisi işlemlerini biz işlem çizilmesine bizim kendi 's yapmak zorunda kalmamak. Temelde başlık altında olan şey, SLSB yöntemine girerken bir işlem başlatmamız ve yöntemden çıkmadan hemen önce bunu taahhüt etmemiz (veya geri almamız). Bu, yapılandırma yerine bir kural örneği, ancak henüz varsayılan, Gerekli olan dışında hiçbir şeye ihtiyacımız olmadı.
Sun'dan Java EE 5 Eğitimi, Kurumsal JavaBeans (EJB'ler) için Gerekli işlem özelliğini şu şekilde açıklamaktadır :
Müşteri bir işlem içinde çalışıyorsa ve kurumsal Bean yöntemini çağırırsa, yöntem müşterinin işlemi içinde yürütülür. İstemci bir işlemle ilişkili değilse, kapsayıcı yöntemi çalıştırmadan önce yeni bir işlem başlatır.
Gerekli özniteliği, kapsayıcı tarafından yönetilen işlem sınırlamasıyla çalışan tüm kurumsal fasulye yöntemleri için örtük işlem özniteliğidir. Başka bir işlem özniteliğini geçersiz kılmanız gerekmedikçe, genellikle Gerekli özniteliği ayarlamazsınız. İşlem öznitelikleri bildirimsel olduğundan, bunları daha sonra kolayca değiştirebilirsiniz.
Sunum
Sunum katmanımız ... sunumdan sorumludur! Kullanıcı arayüzünden sorumludur ve HTML sayfaları oluşturarak ve GET ve POST istekleri aracılığıyla kullanıcı girdisi alarak kullanıcıya bilgileri gösterir. Şu anda eski Servlet'in + Java Sunucu Sayfaları ( JSP ) kombinasyonunu kullanıyoruz.
Katman , kullanıcı tarafından talep edilen işlemleri gerçekleştirmek ve web sayfasında gösterilecek bilgileri almak için iş katmanının yöneticilerindeki yöntemleri çağırır . Bazen iş katmanından alınan bilgiler gibi daha az karmaşık türleridir String
'ler ve int
egers ve diğer zamanlarda en JPA varlıklar .
Mimarinin artıları ve eksileri
Artıları
- Bu katmanda kalıcılık yapmanın belirli bir yolu ile ilgili her şeye sahip olmak, yalnızca, iş katmanında herhangi bir şeyi yeniden yazmak zorunda kalmadan JPA kullanmaktan başka bir şeye geçebileceğimiz anlamına gelir.
- Sunum katmanımızı başka bir şeyle değiştirmek bizim için kolaydır ve daha iyi bir şey bulursak büyük olasılıkla bulacağız.
- EJB konteynerinin işlem sınırlarını yönetmesine izin vermek güzel.
- Servlet'in + JPA'sını kullanmak kolaydır (başlangıçta) ve teknolojiler yaygın olarak kullanılır ve birçok sunucuda uygulanır.
- Java EE kullanımının, yük dengeleme ve yük devretme ile yüksek kullanılabilirlikli bir sistem oluşturmamızı kolaylaştırması gerekiyor . Her ikisine de sahip olmamız gerektiğini düşünüyoruz.
Eksileri
- JPA kullanarak
@NamedQuery
, JPA varlık sınıfındaki açıklamayı kullanarak, sık kullanılan sorguları adlandırılmış sorgular olarak depolayabilirsiniz . Kalıcılık sınıflarında kalıcılıkla ilgili olabildiğince çok şeyiniz varsa, mimarimizdeki gibi, bu, JPA varlıklarını da içerecek sorguları bulabileceğiniz konumlara yayılacaktır. Kalıcılık operasyonlarını gözden geçirmek ve dolayısıyla sürdürmek daha zor olacaktır. - Kalıcılık katmanımızın bir parçası olarak JPA varlıklarımız var. Ama
Account
veShoppingCart
onlar gerçekten iş nesneler değildir? Bu sınıflara dokunmanız ve onları JPA'nın nasıl idare edeceğini bildiği varlıklara dönüştürmeniz gerektiği için bu şekilde yapılır. - Aynı zamanda iş nesnelerimiz olan JPA varlıkları, Değer Nesneleri (VO'lar) olarak da bilinen Veri Aktarım Nesneleri ( DTO'lar ) gibi oluşturulur . Bu , iş nesnelerinin erişimci yöntemleri dışında kendi mantığına sahip olmadığı için anemik bir etki alanı modeliyle sonuçlanır . Tüm mantık, iş katmanındaki yöneticilerimiz tarafından yapılır ve bu da daha prosedürel bir programlama stiliyle sonuçlanır. İyi bir nesne yönelimli tasarım değil, ama belki bu bir sorun değil? (Sonuçta, sonuç veren tek programlama paradigması nesne yönelimi değildir.)
- EJB ve Java EE'yi kullanmak biraz karmaşıklık getirir. Ve tamamen Tomcat kullanamayız (bir EJB mikro-kapsayıcı eklemek tamamen Tomcat değildir ).
- Servlet'in + JPA kullanımıyla ilgili pek çok sorun var. Bu sorunlar hakkında daha fazla bilgi için Google'ı kullanın.
- İş katmanından çıkılırken işlemler kapatıldığı için, ihtiyaç duyulduğunda (kullanılarak
fetch=FetchType.LAZY
) sunum katmanının içinden veritabanından yüklenmek üzere yapılandırılmış JPA varlıklarından herhangi bir bilgi yükleyemiyoruz . Bir istisnayı tetikleyecektir. Bu tür alanları içeren bir varlığı iade etmeden önce, ilgili alıcıları çağırdığımızdan emin olmalıyız. Diğer bir seçenek de Java Persistence Query Language ( JPQL ) kullanmak ve birFETCH JOIN
. Ancak bu seçeneklerin her ikisi de biraz külfetli.