Soru “İş mantığı katmanı” bir MVC uygulamasına nerede sığar?


Öncelikle, kimse dupe çığlık atmadan önce, basit bir başlıkta özetleyen zor bir zaman geçirdim. Başka bir başlık "Bir etki alanı modeli ile MVC modeli arasındaki fark nedir?" veya "Bir model nedir?"

Kavramsal olarak, bir modelin, görünümler ve denetleyici tarafından kullanılan veri olduğunu anlarım. Bunun ötesinde, modeli oluşturan şey hakkında pek çok farklı görüş var gibi görünüyor. Bir uygulama modeli veya bir modele karşı bir etki alanı modeli nedir?

Mesela, yakın zamandaki bir soruda, depo desenini sorduğumda, deponun modelin bir parçası olduğunu boş gösterdim. Ancak, modelin kalıcılık modelinden ve iş mantığı katmanından ayrılması gerektiğine dair diğer görüşleri okudum. Sonuçta, modelden somut sebat yöntemini ayırması gereken Depozit deseni değil mi? Diğer insanlar, Domain modeli ve MVC modeli arasında bir fark olduğunu söylüyor.

Basit bir örnek alalım. MVC varsayılan projesine dahil olan AccountController. Hesap kodunun zayıf tasarım, SRP, vs .. gibi çeşitli görüşleri okudum. Bir MVC uygulaması için "uygun" bir üyelik modeli tasarlayacak 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? Yoksa hiç olmaz mıydı?

Gördüğüm gibi, model "saf" olmalı, belki de doğrulama mantığıyla .. ama iş kurallarından (doğrulamadan) ayrılmalıdır. Örneğin, yeni bir hesap oluşturulduğunda birinin e-posta ile gönderilmesi gerektiğini belirten bir işletme kuralınız olduğunu varsayalım. Bu benim görüşüme göre modele ait değil. Öyleyse nereye ait?

Bu konuda herhangi bir ışık tutturmak isteyen var mı?


82
2017-12-30 19:39


Menşei


Bu yüzden dört ayrı soru sormalısınız. - jfar
Anahtar kelime "neredeyse" dir. Asıl soruyu açıklamak için kullanılan alt sorularla gerçekten aynı soru. - Erik Funkenbusch
Model - Görünüm - Denetleyici. Reposirory / BL Görünümü? Hayır. Denetleyici mi? Hayır, ne kaldı :)? MBVV değil, MRVC değil, MSVC değil, MVC'dir. Sadece üç katman var. Yani depo modelin bir parçası, BL modelin bir parçasıdır. Ve ek ayrılık yapabilir, ancak model katmanın içinde yapılır. - LukLed
@LukeLed, @bslm - Pek değil. MVC, denetleyicinin veya modelin etkileşim kurduğu başka katmanların olamayacağını söylemez. - jfar
@LukLed - Katılmıyorum - MVC sadece bir sunum katmanı modelidir. BLL ve DAL gibi diğer katmanlarınızı nasıl yapılandıracağınız üzerinde hiçbir etkisi yoktur. - Cory House


Cevaplar:


Yaptığım şekilde - ve doğru ya da yanlış olduğunu söylemiyorum, Görüşüm'e sahip olmak ve benim görüşüm için geçerli bir model. Bu model, yalnızca veri ek açıklamaları ve geçerlilik kuralları dahil olmak üzere, görünümümle alakalı olanı içerir. Kontrolör sadece 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.

Etki alanı nesnelerim ayrı olarak barındırılıyor (aslında kendi projelerinde). Kendi veri ek açıklamaları ve doğrulama kuralları vardır. Depomum, alan adımdaki nesneleri veritabanına kaydetmeden önce doğrular. Etki alanımdaki her nesne, yerleşik olarak doğrulanmış bir temel sınıftan devraldığı için, havuzum geneldir ve her şeyi doğrular (ve temel sınıftan miras almasını gerektirir).

İki takım modele sahip olmanın kodun çoğaltılması olduğunu düşünebilirsiniz, ve bir dereceye kadar. Ancak, etki alanı nesnesinin görünüm için uygun olmadığı mükemmel mantıklı örnekler vardır.

Önemli olan nokta, kredi kartlarıyla çalışırken - ödeme yaparken bir cvv'ye ihtiyaç duymak zorundayım, ancak cvv'yi saklayamıyorum (bunu yapmak için 50.000 dolarlık bir para cezası). Ancak, kredi kartınızı düzenleyebilmenizi istiyorum; adres, ad veya son kullanma tarihi. Ancak, düzenlerken numarayı veya cvv'yi bana vermeyeceksin ve kesinlikle kredi kartı numaranızı sayfaya düz metin olarak yazmayacağım. Alan adımın, bana verdiğiniz için yeni bir kredi kartı kaydetmek için gereken bu değerleri vardır, ancak düzenleme modelim kart numarasını veya cvv'yi içermez.

Pek çok katmana yönelik bir diğer fayda, doğru bir şekilde düzenlendiyse, structuremap veya başka bir IoC konteynerini kullanabilir ve uygulamanızı olumsuz yönde etkilemeden parçaları değiştirebilirsiniz.

Bence, denetleyici kodu sadece görünümde hedeflenen kod olmalıdır. Bunu gösterin, gizleyin, vb. Hizmet katmanınız uygulamanız için iş mantığına sahip olmalıdır. Hepsinin tek bir yerde olmasını seviyorum, böylece bir iş kuralını değiştirmek veya değiştirmek kolaydır. Depo katmanı nispeten aptal olmalı - iş mantığından yoksun olmalı ve sadece verilerinizi sorgulayın ve etki alanı nesnelerini döndürün. Görünüm modellerini etki alanı modelinden ayırarak, özel doğrulama kuralları söz konusu olduğunda çok daha fazla esnekliğe sahip olursunuz. Ayrıca her bir veri parçasını gizli alanlardaki görünümünüze dökmeniz ve istemciyle sunucu arasında ileri geri itmeniz (veya arka planda yeniden oluşturmanız) gerekmediği anlamına gelir. Görünüm modeliniz daha sonra yalnızca görünümle ilgili bilgileri barındırır - ve bu, mantığın veya sayımların veya enumların görüntülenmesi için bir havuza sahip olacak şekilde özelleştirilebilir, böylece görünümün kendisi gibi karmaşık mantık ifadeleriyle karışıklık göstermez.

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

Her şey yayılmış ve aşırı katmanlı görünüyor olsa da, bu şekilde mimarlık yapmanın bir amacı var. Mükemmel mi? pek sayılmaz. Ancak kontrolörden depoları arama ve kontrolör, depo ve modelde karışık iş mantığına sahip bazı geçmiş tasarımlara tercih ediyorum.


67
2017-12-30 20:08



+1 josh. Bu, neredeyse bir şeyleri nasıl yaptığımızın bir faktörüdür. - jim tollan
Sadece kurumsal MVC uygulamasında sahip olduğum şeyin aynası. Bir N-Tier mimarisi. MVC uygulaması sadece N-Tier alanlarında iş nesneleri ve hizmetleri ile etkileşime girer. - Ed DeGagne
Çoğunlukla burada aynı. Tanımlar, modeller, görünüm modülleri, DAL, vb. İçin ayrı projeler. Tek fark, DAL'imin web için verileri, raporlar veya özel müşteri görüşleri için karmaşık verilerin dağıtımını optimize etmek üzere düzleştirmek için mantığı içerdiği. Şu anda, oyun masalarında, Web çiftlikleri ve Azure bulutları ile, uygulama önbelleklerini uygulamadan uzak tutuyorum. - Robert Achmann
Biraz kod paylaşır mısın? - ebram khalil
@Josh, örnek projenizin ekran görüntüsünü gösterebilirseniz yararlı olur mu? - stom


MVC elemanlarının geleneksel web uygulama yapısına tam olarak ne kadar uyduğunu merak ettim, burada (sayfalar), kontrolörler, servisler ve veri nesneleri (model) var. Dediğin gibi, bunun birçok versiyonu var.

"Anemik alan modeli" (iddia edilen) -antilasyon modelini kullanan, yukarıda belirtilen, yaygın kabul gören mimariden dolayı karışıklığın varlığına inanıyorum. Anemik veri modelinin "anti-patternness" i hakkında fazla ayrıntıya girmeyeceğim (şeyleri açıklamak için benim bir çabaya bakabilirsin) İşte (Java tabanlı, ancak herhangi bir dil için uygun)). Ama kısacası, bu bizim modelimizin sadece veri tuttuğu ve iş mantığının hizmetlere / yöneticilere yerleştirildiği anlamına gelir.

Ama varsayalım var etki alanı odaklı mimarive bizim etki alanı nesnelerimiz olması beklenen şeydir - hem devlet hem de iş mantığına sahip olmak. Ve bu alan odaklı perspektifte şeyler ortaya çıkıyor:

  • görüş UI
  • denetleyici, kullanıcı arabiriminin girişlerini toplar, modeldeki yöntemleri çağırır ve kullanıcı arabirimine bir yanıt gönderir
  • model, iş bileşenlerimizdir - verileri tutarak, aynı zamanda iş mantığına sahiptir.

Sanırım bu, ana sorularınızı cevaplıyor. Depo katmanı gibi bazı katmanlar eklediğimizde işler karmaşıklaşır. Genellikle modele yerleştirilen iş mantığı tarafından çağrılması gerektiği önerilmektedir (ve dolayısıyla her bir alan nesnesi bir depoya bir referansa sahiptir). Bağlantı kurduğum makalede bunun en iyi uygulama olmadığını iddia ediyorum. Ve aslında bir hizmet katmanına sahip olmak kötü bir şey değil. Bu arada, alan odaklı tasarım servis katmanını hariç tutmaz, ancak 'ince' olması ve sadece alan adı nesnelerini koordine etmesi gerekir (böylece iş mantığı yoktur).

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


16
2017-12-30 20:07



+1 Bir java geliştiricisi gibi konuştu ;-) - Eddie B
Mükemmel nokta! Bir yorum: Hizmetler ile aynı karışıklık var. En azından hizmetler, Uygulama hizmetleri ve Alan adı hizmetleri olabilir. Uygulama hizmeti, Depolar, vb. Bilgileri toplayan sadece ince bir sarıcıdır. Etki alanı hizmeti, etki alanı modellerinin birleşimini veya yalnızca etki alanı modelinde her zaman sığmayan şeyleri kullanarak iş mantığı sağlar. - Artru
projenizde veritabanı yoksa ne olur? Servis referansları ile etkileşime girer. Tüm etki alanı sınıfları ve yöntemleri bu referanslardan gelir. Bu senaryo katmanlı yapıya uygun mu? - user6395764


Benim fikrimce,

Model -

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

İş mantığı -

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

Uygulama Hizmetleri, iş mantığını uygulamak ve en sonunda Modeli döndürmek için Etki Alanı Hizmetleri katmanına konuşur.

Yani, Kontrolör, Model için Uygulama Hizmeti isteyecek ve akış,

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

3
2017-12-30 20:14





MVC modeli 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. Modelde olmanın üyeliği hakkındaki sorunuz. Bu değişir. Modelinizde sınıflar bir şeye ait mi? Oturum açan ve hangi verinin görüntülendiği arasında bir bağlantı var mı? Düzenlenebilir bir izin sisteminin veri bölümünün filtrelenmesi var mı? Alan adınızın bir nesnesinin son bölümünün en son kimin tarafından güncellendiği veya düzenlendiği, arka plan desteği için bir şeyler mi görmek istiyor?

E-posta örneği de bağlıdır. Özellikle alandaki etkinliklere veya olaylara aşina mısınız? E-posta göndermek için ayrı bir servisiniz var mı? Alan adınızın bir e-posta bölümünü gönderme ya da sisteminizin kapsamı dışında bir uygulama seviyesi endişesi mi? UI'nin bir e-postanın başarıyla gönderilip gönderilmediğini bilmesi gerekiyor mu? Göndermeyen e-postalar yeniden denenmeye ihtiyaç duyuyor mu? Gönderilen e-postanın içeriği destek veya müşteri hizmetleri gereksinimleri için saklanmak zorunda mı?

Bu tür sorular aşırı geniş ve özneldir ama ben size cevap veriyorum, siz ve siz oy verdiğiniz herkes bunu anlayabilir.

Gereksinimleriniz / zaman çizelgeleriniz / kaynaklarınız sisteminizin mimarisine sızıyor. Hatta gelir modeli bir etkisi olabilir. Ayrıca çekim yapmakta olduğunuz deseni de göz önünde bulundurmalısınız. DDD, model olarak kalıcılığı olan uygulamalardan çok farklıdır ve aradaki tüm slop, belirli uygulamalar için de geçerlidir. Uygulamayı test etmek için mi çekiyorsunuz? Bütün bunların bir etkisi var.


2
2017-12-30 20:09