"İş mantığı katmanı" bir MVC uygulamasına nerede uyuyor?


87

Birincisi, kimse dupe çığlık atmadan önce, basit bir başlıkta özetlemekte zorlandım. Başka bir başlık da "Bir etki alanı modeli ile MVC modeli arasındaki fark nedir?" veya "Model nedir?"

Kavramsal olarak, bir Modeli, görünümler ve denetleyici tarafından kullanılan veri olarak anlıyorum. Bunun ötesinde, modeli neyin oluşturduğuna dair çok sayıda farklı görüş var gibi görünüyor. Etki alanı modeli nedir, uygulama modeli, görünüm modeli, hizmet modeli vb.

Örneğin, depo modeli hakkında sorduğum yakın tarihli bir soruda, havuzun modelin bir parçası olduğu boş gösterildi. Ancak modelin kalıcılık modelinden ve iş mantığı katmanından ayrılması gerektiğine dair başka görüşler okudum. Sonuçta, Depo modelinin somut kalıcılık yöntemini modelden ayırması gerekmiyor mu? Diğer insanlar, Etki Alanı modeli ile MVC modeli arasında bir fark olduğunu söylüyor.

Basit bir örnek verelim. MVC varsayılan projesine dahil olan AccountController. İçerdiği Hesap kodunun kötü tasarıma sahip olduğuna, SRP'yi ihlal ettiğine vb. Dair birkaç görüş okudum. Bir MVC uygulaması için "uygun" bir Üyelik modeli tasarlanacak olsaydı, bu ne olurdu?

ASP.NET hizmetlerini (Üyelik sağlayıcısı, rol sağlayıcısı, vb.) Modelden nasıl ayırırsınız? Ya da hiç mi yapardın?

Gördüğüm gibi, model "saf" olmalı, belki de doğrulama mantığı ile .. ama iş kurallarından ayrı olmalıdır (doğrulama dışında). Örneğin, yeni bir hesap oluşturulduğunda birisine e-posta gönderilmesi gerektiğini söyleyen bir iş kuralınız olduğunu varsayalım. Benim görüşüme göre bu gerçekten modele ait değil. Peki nereye ait?

Bu konuya ışık tutmak isteyen var mı?


1
Bu yüzden dört ayrı soru sormalısınız.
John Farrell

3
Anahtar kelime "neredeyse" dir. Bu gerçekten aynı soru, belki de birincil soruyu açıklamak için kullanılan alt sorular.
Erik Funkenbusch

3
Model - Görünüm - Denetleyici. Depo / BL Görünümü mü? Hayır. Denetleyici mi? Hayır. Ne kaldı :)? Bu MVC'dir, MSVC değil, MRVC değil, MBLVC değil. Sadece üç katman var. Dolayısıyla depo modelin bir parçasıdır, BL modelin parçasıdır. Ve ek ayırma yapabilirsiniz, ancak bu model katmanının içinde yapılır.
LukLed

3
@LukeLed, @bslm - Pek değil. MVC, denetleyicinin veya modelin etkileşim kurduğu başka katmanların olamayacağını söylemiyor.
John Farrell

3
@LukLed - Katılmıyorum - MVC yalnızca bir sunum katmanı modelidir. BLL ve DAL gibi diğer katmanlarınızı nasıl yapılandırdığınız üzerinde hiçbir etkisi yoktur.
Cory Evi

Yanıtlar:


69

Bunu yapma şeklim - ve bunun doğru ya da yanlış olduğunu söylemiyorum, Benim Görüşüme ve sonra benim görüşüme uygun bir modele sahip olmaktır. Bu model, veri açıklamaları ve doğrulama kuralları dahil olmak üzere yalnızca benim görüşümle alakalı olanlara sahiptir. Denetleyici yalnızca modeli oluşturmak için mantığı barındırır. Tüm iş mantığını barındıran bir hizmet katmanım var. Denetleyicilerim hizmet katmanımı çağırıyor. Bunun ötesinde benim depo katmanım var.

Etki alanı nesnelerim ayrı olarak barındırılıyor (aslında kendi projelerinde). Kendi veri açıklamaları ve doğrulama kuralları vardır. Depom, alanımdaki nesneleri veritabanına kaydetmeden önce doğrular. Etki alanımdaki her nesne, yerleşik doğrulamaya sahip bir temel sınıftan miras aldığından, depom geneldir ve her şeyi doğrular (ve temel sınıftan miras almasını gerektirir).

İki model setine sahip olmanın kodun kopyası olduğunu düşünebilirsiniz ve bir dereceye kadar öyle. Ancak, etki alanı nesnesinin görünüm için uygun olmadığı tamamen makul durumlar vardır.

Konu, kredi kartlarıyla çalışırken - Bir ödemeyi işlerken bir cvv'ye ihtiyacım var, ancak cvv'yi saklayamıyorum (bunu yapmak 50.000 $ para cezasıdır). Ama aynı zamanda kredi kartınızı - adres değişikliği, isim veya son kullanma tarihi değiştirebilmenizi de istiyorum. Ama düzenlerken bana numarayı veya cvv'yi vermeyeceksiniz ve kesinlikle kredi kartı numaranızı sayfaya düz metin olarak yazmayacağım. Etki alanım, bana verdiğiniz için yeni bir kredi kartı kaydetmek için gereken bu değerlere sahip, ancak benim düzenleme modelim kart numarasını veya cvv'yi bile içermiyor.

Bu kadar çok katmanın bir başka yararı da, doğru bir şekilde tasarlanmışsa, yapı haritası veya başka bir IoC konteyneri kullanabilir ve uygulamanızı olumsuz yönde etkilemeden parçaları değiştirebilmenizdir.

Bana göre, denetleyici kodu yalnızca görünümde hedeflenen kod olmalıdır. Bunu gösterin, gizleyin, vb. Hizmet katmanı, uygulamanız için iş mantığını barındırmalıdır. Hepsinin tek bir yerde olmasını seviyorum, böylece bir iş kuralını değiştirmek veya ince ayar yapmak kolaydır. Depo katmanı göreceli olarak aptal olmalıdır - iş mantığından yoksun olmalı ve yalnızca verilerinizi sorgulayıp etki alanı nesnelerinizi iade etmelidir. Görünüm modellerini alan modelinden ayırarak, özel doğrulama kuralları söz konusu olduğunda çok daha fazla esnekliğe sahip olursunuz. Ayrıca, her veri parçasını gizli alanlardaki görünümünüze dökmeniz ve istemci ile sunucu arasında ileri geri itmeniz (veya arka uçta yeniden oluşturmanız) gerekmediği anlamına gelir.

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %>

Her şey dağınık ve aşırı katmanlı görünse de, bu şekilde mimarlık için bir amacı vardır. Mükemmel mi pek sayılmaz. Ancak, denetleyiciden depoları çağırma ve denetleyici, havuz ve modelde karışık iş mantığına sahip bazı geçmiş tasarımlara tercih ederim.


Kurumsal MVC uygulamamızda sahip olduğum şeyin bir aynası. N-Katmanlı bir mimari. MVC uygulaması yalnızca N-Katman alanlarındaki iş nesneleri ve hizmetlerle etkileşime girer.
Ed DeGagne

Çoğunlukla burada aynı. Tanımlar, modeller, görünüm modelleri, DAL, vb. İçin ayrı projeler. Tek fark, DAL'imin raporlar veya özel müşteri görünümleri için karmaşık verilerin dağıtımını optimize etmek için web için verileri düzleştirme mantığını içermesidir. Artık Web çiftlikleri ve Azure bulutları oyundayken, arama tabloları vb. İçin bir şeyleri uygulama önbelleğinde tutmaktan çekiniyorum.
Robert Achmann

1
@Josh, örnek projenizin ekran görüntüsünü göstermeniz faydalı olur mu?
Shaiju T

@Josh ya projenizin veritabanı yoksa. Servis referanslarıyla etkileşim halindedir. Tüm alan sınıfları ve yöntemi bu referanslardan gelir. Bu senaryo katmanlı yapıya uygun mu?
user6395764

17

MVC öğelerinin, görünümler (sayfalar), denetleyiciler, hizmetler ve veri nesnelerine (model) sahip olduğunuz geleneksel bir web uygulaması yapısına tam olarak nasıl uyduğunu çok sık merak ettim. Dediğin gibi, bunun birçok versiyonu var.

Bence karışıklık, yukarıda belirtilen, yaygın olarak kabul edilen ve "anemik alan modeli" (iddia edilen) -anti modelini kullanan mimari nedeniyle var. Anemik veri modelinin "anti-modelliği" hakkında çok fazla ayrıntıya girmeyeceğim ( burada bir şeyleri açıklama çabalarıma bakabilirsiniz (Java tabanlı, ancak herhangi bir dille ilgili)). Ancak kısaca, modelimizin yalnızca verileri tuttuğu ve iş mantığının hizmetlere / yöneticilere yerleştirildiği anlamına gelir.

Ancak, etki alanına dayalı mimariye sahip olduğumuzu ve etki alanı nesnelerimizin beklenen şekilde olduğunu varsayalım - hem durum hem de iş mantığına sahip. Ve bu etki alanına dayalı perspektifte işler devreye girer:

  • görünüm, kullanıcı arayüzüdür
  • denetleyici, kullanıcı arayüzünün girdilerini toplar, modeldeki yöntemleri çağırır ve kullanıcı arayüzüne bir yanıt gönderir
  • bu model bizim iş bileşenlerimizdir - verileri tutan, aynı zamanda iş mantığına da sahip.

Sanırım bu ana sorularınızı yanıtlıyor. Depo katmanı gibi daha fazla katman eklediğimizde işler karmaşıklaşır. Genellikle modele yerleştirilen iş mantığı tarafından çağrılması önerilir (ve bu nedenle her etki alanı nesnesinin bir havuza referansı vardır). Bağladığım makalemde bunun pek iyi bir uygulama olmadığını iddia ediyorum. Ve bu aslında bir hizmet katmanına sahip olmak kötü bir şey değil. Bu arada, etki alanına dayalı tasarım hizmet katmanını dışlamaz, ancak 'zayıf' olması ve yalnızca etki alanı nesnelerini koordine etmesi gerekir (yani burada iş mantığı yoktur).

Yaygın olarak benimsenen (iyi veya kötü için) anemik veri modeli paradigması için, model hem hizmet katmanı hem de veri nesneleriniz olacaktır.


Mükemmel nokta! Bir not: Hizmetlerle aynı karmaşa var. En azından hizmetler Uygulama hizmetleri ve Etki alanı hizmetleri olabilir. Uygulama hizmeti, Depolardan vb. Bilgi toplayan ince bir paketleyicidir. Etki alanı hizmeti, etki alanı modellerinin kombinasyonunu veya etki alanı modeline her zaman uymayan şeyleri kullanan iş mantığı sağlar.
Artru

Ya projenizin veritabanı yoksa. Servis referanslarıyla etkileşim halindedir. Tüm alan sınıfları ve yöntemi bu referanslardan gelir. Bu senaryo katmanlı yapıya uygun mu?
user6395764

3

Bence,

Model -

İş mantığı içermemelidir, takılabilir olmalıdır (WCF benzeri senaryo). Görmek için bağlanmak için kullanılır, bu yüzden özellikleri olmalıdır.

İş mantığı -

"Etki Alanı Hizmetleri Katmanı" na yerleştirilmelidir, tamamen ayrı bir katmandır. Ayrıca, buraya "Uygulama Hizmetleri" bir katman daha ekleyecektir.

Uygulama Hizmetleri, iş mantığını uygulamak için Etki Alanı Hizmetleri katmanıyla görüşür ve son olarak Modeli döndürür.

Dolayısıyla, Denetleyici Uygulama Hizmetinden Model için soracak ve akış şöyle devam edecek:

    Controller->Application Services(using domain services)->Model

2

MVC kalıbı ve Asp.net çerçevesi, Modelin ne olması gerektiği konusunda hiçbir ayrım yapmaz.

MS'in kendi örnekleri, modeldeki kalıcılık sınıflarını içerir. Üyeliğin modelde olmasıyla ilgili sorunuz. Bu bağlıdır. Modelinizdeki sınıflar bir şeye mi ait? Kimin oturum açtığı ve hangi verilerin görüntülendiği arasında bir bağlantı var mı? Düzenlenebilir bir izin sisteminin veri kısmına filtre uygulanıyor mu? Etki alanınızın bir nesnesini, başka birinin görmesi gerektiği gibi veya arka uç desteği için bir şeyi en son kim güncelledi veya düzenledi?

E-posta örneği de buna bağlıdır. Özellikle etki alanı olaylarını veya olaylarını biliyor musunuz? E-posta göndermek için ayrı bir hizmetiniz var mı? E-posta gönderme eylemi alanınızın bir parçası mı yoksa uygulama düzeyinde bir sorun mu, sisteminizin kapsamı dışında? Kullanıcı arayüzünün bir e-postanın başarıyla gönderilip gönderilmediğini bilmesi gerekiyor mu? Gönderilemeyen e-postaların yeniden denenmesi gerekiyor mu? Destek veya müşteri hizmetleri gereksinimleri için gönderilen e-postanın içeriğinin saklanması gerekiyor mu?

Bu tür sorular aşırı geniş ve özneldir, ancak ben yanıtlıyorum, böylece siz ve size oy veren herkes bunu anlayabilirsiniz.

Gereksinimleriniz / zaman çizelgeleriniz / kaynaklarınız, sisteminizin mimarisine dahil edilir. Gelir modelinin bile bir etkisi olabilir. Ayrıca, çekim yaptığınız modeli de göz önünde bulundurmalısınız. DDD, model olarak kalıcılık uygulamalarından çok farklıdır ve aradaki tüm eğim, belirli uygulamalar için de geçerlidir. Uygulamayı test etmek için mi çekim yapıyorsunuz? Bütün bunların bir etkisi var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.