MV* kalıpları olmadan yazılan karmaşık uygulama kodunun test edilmesi, yeniden kullanılması ve bakımı zordur. Kalıplar Görünüm, Model ve Denetleyici arasındaki bağlantıyı ortadan kaldırır veya zayıflatır, kodu ayırır ve geliştirmeyi basitleştirir. MV* kalıplarının türlerini ve SimpleOne’daki kullanımlarını ele alacağız.
Bir SimpleOne uygulaması geliştirirken, kullanıcı arayüzünü (UI) dikkatlice tasarlar ve müşterilerimizin platformu kullanmasını kolay ve rahat hale getirmek için kullanıcı deneyimini (UX) tasarlarız. Ancak kullanıcı arayüzü, kullanıcı (Kullanıcı) tarafından görülen buzdağının yalnızca görünen kısmıdır. Düğmelerin ve alanların arkasında ölçeklenebilir, bakımı yapılabilir ve güvenilir olması gereken kodlar yatar. Bu sorunları çözmek için geliştiriciler, UI kodunu, mantığı ve veri işlemeyi ayırmak için kullanılan MV* kalıplarını uygular.
Desenler olmadan kullanıcı arayüzü
Çeşitli öğeler ve widget’lar içeren bir forma sahip bir uygulama hayal edelim. Bu formun kodu hem mantığın açıklamasını hem de kullanıcı arayüzü öğelerinin kodunu içerir ve ayrıca veri işleme için parçalar da içerebilir. Basit bir uygulama için, bu programlama ilkesini desteklemek bir sorun değildir. Her an karşılıklı ilişkileri bulabilir ve bütünlüğü bozmadan değişiklikler yapabilirsiniz. Uygulama daha karmaşık hale geldiğinde, kalıplar olmadan yazılmış bir arayüzü desteklemek sorun haline gelir.
Sorun, tek sorumluluk ilkesinin ihlal edilmesinden kaynaklanmaktadır (single responsibility principle) – “Bir sınıfın değişmesi için yalnızca bir nedeni olmalıdır”. Hem kullanıcı arayüzü kodu (View), hem mantık (Controller), hem de veri işleme (Model) bir arayüzde toplandığından, değiştirmek için birden fazla nedenimiz vardır. Bir bileşenin kodunu değiştirdiğimizde, diğer bileşenleri de değiştirmemiz gerekir. Bu durum uygulama desteğini zorlaştırır, otomatik test yapmak neredeyse imkansızdır ve kodun yeniden kullanımı çok sınırlıdır.
Bu nedenle kalıpları kullanmak uygun ve doğrudur – UI kodunu (View), mantık kodunu (Presenter, Controller, ViewModel ve diğerleri) ve veri işleme kodunu (Model) ayırırlar. Kullanıcı arayüzünü değiştirmeden mantığı kolayca değiştirebilir veya yalnızca veri işleme rutinlerinde değişiklik yapabiliriz. Her bir model diğerlerinden bağımsız olarak test edilebilir ve başka uygulamalarda da kullanılabilir.
En yaygın kullanılan modeller Model-View-Controller, Model-View-Presenter ve Model-View-View-Model‘dir. Şimdi bunların nasıl farklılaştığına ve nerede uygulandıklarına bir göz atalım.
Model ve Görünüm
Söz konusu üç modelin de tekrar eden iki bileşeni vardır. Özellikleri farklıdır, ancak özünde aynıdırlar.
Görünüm görsel bir arayüzdür (UI). Tek tek öğelerden veya widget’lardan oluşabilir. Görünüm örnekleri MFC ve WinForms’ta form oluşturma kodu, ASP.NET’te html, WPF ve Silverlight’ta XAML’dir.
Model, arayüz kullanılarak görüntülenen uygulama verileri ve bunları alma ve kaydetme işlemidir.
Model-View-Controller
Smalltalk’ta uygulama geliştirmek için 1979 yılında geliştirilen en eski model. O zamanlar standart öğeleriyle birlikte Windows grafik kabuğu yoktu. Arayüz manuel olarak kodla oluşturuluyordu. Ancak, o zaman bile görüntü, mantık ve veri kodunun ayrılması geliştirmede bir devrimdi.
Bu modelde üç ana unsur görüyoruz:
- Model – uygulama verileri ile bunları alma ve kaydetme mantığı. Çoğu zaman model, bir veritabanından gelen verilerle veya web hizmetlerinin sonuçlarıyla çalışır. Veriler ya hemen ekranda görüntülenir ya da uyarlanır.
- View – görsel arayüz, düğmeleri, etiketleri, giriş alanlarını ve diğer form öğelerini oluşturma. Modeli takip edebilir ve ondan veri görüntüleyebilir.
- Controller – kullanıcı eylemlerini (klavye düğmeleri veya fare hareketleri) izler, bunlarla ne yapılacağına karar verir ve Model ve Görünümü günceller.
MVC modelinin prensibini aşağıdaki gibi açıklayalım. Denetleyici kullanıcı eylemlerini işler – fare tıklamaları, klavyeye basmalar veya gelen http istekleri. İşlenen değişiklikler Controller tarafından Model’e aktarılır ve View üzerinde çizilir (pasif mod) ya da Model değişiklikleri doğrudan View’dan alır (aktif mod). View’un ana görevi, Controller’ı kullanarak Model’den gelen verileri render etmektir.
Model-View-Presenter
Görsel programlama ve widget’ların geliştirilmesi, tek tek View öğelerinin oluşturulmasını ortadan kaldırmıştır, bu nedenle artık ayrı bir Denetleyici sınıfına gerek yoktur. Öğeler, kullanıcının kendileriyle hangi eylemleri gerçekleştirdiğini bilir. Ancak uygulama mantığını verilerden ayırmak hala gereklidir. Böylece, kalıp Controller yerine Presenter ile değiştirildi.
MVC ile karşılaştırıldığında, Model işlevi değişmedi, View artık kullanıcı eylemlerini (örneğin widget’ları kullanarak) işliyor ve bu eylem arayüz mantığında bir şeyi değiştirirse, Presenter’a aktarılıyor.
Bu kalıbın ana görevi, değiştirilebilir Görünümler gerçekleştirmek ve bunları bağımsız olarak test edebilmek için Görünüm’ü Denetleyici’den ayırmaktır.
Bir iletken olarak Presenter, Model ve View’un senkronize çalışmasından sorumludur. Bir kullanıcı eylemi hakkında View’dan bir bildirim alırsa, modeli günceller ve değişiklikleri View ile senkronize eder. Tüm iletişim arayüz aracılığıyla gerçekleşir, bu da onlara ayrılık sağlar.
MVC’nin iki uygulaması vardır: Görünümün Model hakkında hiçbir şey bilmediği ve Sunucunun Modelden bilgi almak ve Görünümü güncellemekten sorumlu olduğu Pasif Görünüm ve Görünümün Model hakkında bilgi sahibi olduğu ve verileri ekranın kendisine bağladığı Denetleyici Denetleyici.
Model-View-View-ViewModel
Bu model ile diğerleri arasındaki en önemli fark, WPF ve Silverlight’ta veri bağlama özelliğinin bulunmasıdır.
Burada ViewModel ve View arasında doğrudan bir iletişim yoktur, özellikler ve yöntemlerden oluşan komutlar (bağlama) aracılığıyla yapılır. Doğru özelliklere sahip olduğunuz sürece herhangi bir View ve ViewModel’i bu şekilde bağlayabilirsiniz. XAML bağlama ayrıca View’e yalnızca verileri değil eylemleri de bağlamanıza olanak tanır. Bir nesneyi Model özelliği olarak tanımlarız ve bildirimsel olarak View’daki ilgili özelliğe bağlarız. Çıktı, View’dan bağımsız olarak hem veri hem de davranış içeren ayrı bir nesnedir. ViewModel, Model ve Controller’ın bir kombinasyonudur.
MVVM’nin başlıca avantajları kolay arayüz tasarımı, bağımsız test ve View için azaltılmış koddur.
Optimizasyon ve performans
Görünüm, Model ve Denetleyici kodunu ayırmak için MV* kalıplarını kullanırsak, yüksek yüklü sistemlerde, bu öğeleri farklı hesaplama birimlerine ayırarak ek bir fayda elde edilebilir.
- Görüntü istemci cihazına (dizüstü bilgisayar, PC, akıllı telefon) getirilir. SPA tek sayfa uygulama teknolojisi hızlandırma işleminden sorumludur. Karmaşık hesaplamalar kullanıcının uç noktasında gerçekleştirilir, böylece arka uç sunucular üzerindeki yük azaltılır.
- Controller (Presenter, ViewModel), mantığı işleyen ayrı bir arka uç sunucusuna taşınır.
- Model en hacimli ve üretken unsurdur, bu nedenle hızlı bir veri depolama sistemine ve tercihen RAM’de “sıcak” bilgileri önbelleğe alma yeteneğine sahip bir sunucu gerektirir.
SimpleOne’da MVC
ITSM-system SimpleOne geliştirilirken, Model-View-Controller modeli temel alınır ve bu model önemli ölçüde optimize edilir. Görünüm rolü, tamamen istemci cihazda çalışan ve yalnızca Model’den veri alan tek sayfalık bir SPA uygulaması tarafından oynanır. Modelin çalışması için DDD yaklaşımını kullanıyoruz (Domain-Driven Design) – örüntüyü verilere erişilen katmanlara (depolara) ayırıyoruz.
Geleneksel MVC’de Model kodu, PostgreSQL gibi belirli bir veritabanı ve sözdizimi için tasarlanmıştır. Depo sistemini kullanarak, uygulama kodunu değiştirmeden katmanları değiştirebilir ve başka herhangi bir veritabanına bağlanabiliriz.
Katmanlar sadece veritabanına bağlayıcılar olarak depolarla çalışmamıza değil, aynı zamanda herhangi bir sınıfı ayrı varlıklara bölmemize de olanak tanır. Örneğin, normal bir MVC Modelinde Kullanıcı sınıfı birkaç bin satır kod içeriyorsa ve kullanıcıyla ilgili tüm işlemlerden (arama, silme, mesaj gönderme ve diğerleri) sorumluysa, SimpleOne’da bunu birkaç ayrı katmana ayırırız: kullanıcı tanımı sınıfı, veritabanıyla çalışmak için kullanıcı deposu, kullanıcıyla ilgili çeşitli hizmetlerin sınıfları ve diğerleri. Bir MVC çerçevesi elde ediyoruz, ancak daha derinlemesine geliştirilmiş, değiştirmeye izin veren, çok daha hızlı sorgu yürütme ve daha sürdürülebilir.
Sonuç
Kalıplar, mükemmel bir kod organizasyonu oluşturmak için takip edilmesi gereken katı paradigmalar değildir. Çok önemli sorunları çözerler – Görünüm, Model ve Denetleyici arasındaki bağlantıları zayıflatmak (ortadan kaldırmak) ve kullanıcı arayüzü geliştirmenin karmaşıklığını azaltmak. Bu yaklaşımın gerçekleştirilmesi, ara bağlantıların özünü anlamanız ve her bir projede bunların ortadan kaldırılma olasılığını aramanız halinde mümkündür. ESM sistemi SimpleOne karmaşık ve geliştirme açısından ağır bir platform olmasına rağmen kullanıcı dostu bir arayüz sunar ve ağır yüklerin üstesinden gelebilir. Bu verimlilik, MV* kalıplarının kullanımı da dahil olmak üzere modern teknolojilerin ve geliştirme yöntemlerinin kullanılmasının bir sonucudur.