Modele, görünüme veya kontrolöre sıralama mantığı yerleştirilmeli mi? [kapalı]


157

Bir tablodan son kullanıcıya değerleri gösteren bir açılır liste var. Bu değerlerin alfabetik olarak sıralanmasını istiyorum.

Uygun MVC tasarımına göre, sıralama mantığımı hangi katmana yerleştirmeliyim: model, görünüm veya kontrolör?

DÜZENLEME : LarsH'nin "Hangi sıralama düzeninin istendiğini belirleyen kod mu demek istediniz?" Veya sıralama yapan kodu mu? "


6
Yorumlardaki anlaşmazlığı çözmek için, "mantığı sıralayarak" ne demek istediğinizi söylerseniz yardımcı olur. İstediğiniz sıralama düzenini belirleyen kodu mu kastediyorsunuz? veya sıralama yapan kod?
LarsH

9
MVC tasarımı özel veya sihirli bir şey değil - gerçekten sadece bir başlangıç ​​noktası. ihtiyaçlarınızı karşılayın ve istediğiniz zaman yeniden düzenleyebileceğinizi unutmayın. Farklı tedarikçilerin, araç setinin ihtiyaçlarına göre denetleyiciye veya görünümü nelerin değiştireceğini yeniden belirledik, böylece herhangi bir anlaşma bulmak zor. Önemli olan Modelinizi Görünüm / Denetleyicinizden ayırmaktır. Ayrıca MVP modelinden daha fazla kilometre alabilirsiniz, tam olarak bu alanda biraz daha spesifik olduğuna inanıyorum.
Bill K

9
Belki bu Programcılara taşınmalıdır.
Alfredo Osorio

57
Kesinlikle kontrolörde. Ya bu ya da model. Ya da manzara.
mafya

2
Kesinlikle asla, asla, asla, asla görüşte.
contactmatt

Yanıtlar:


49

(Not: Bu alıntı ve alıntı @ dasblinkenlight'ın cevabından alınmıştır , ancak yorumumuza katılmıyoruz. Yazısını okuyun ve kendi kararınızı verin).

MVC açıklamasına göre ,

Bir denetleyici, görünümün modelin sunumunu değiştirmek için ilişkili görünümüne komutlar gönderebilir (örneğin, bir belgeyi kaydırarak). Modelin durumunu güncellemek için modele komutlar gönderebilir (örn. Bir belgeyi düzenlemek).

Sıralama mantığı (örneğin, sıralama karşılaştırıcısı / sıralama algoritması), iş kuralları ve durum verileri içerdiği için modele aittir. Model verilerinin sıralanma şeklini değiştirmek "görünümün modelin sunumunu değiştir" kategorisine girdiğinden, denetleyici model.changeSortedState () yöntemini çağırarak "sıralama yapmaktan" sorumludur.


8
Aynı veriler farklı şekilde sıralanmış iki farklı görünümde görüntülenecekse ne olur?
s4y

Bu, model.SortAscending () ve model.SortDescending () ile aynı şekilde yapılmalı ve Controller tarafından çağrılmalıdır.
Brij

1
@Brij Uygun MVC'de iki görünüm aynı modeli paylaşamaz mı?
KOVIKO

@Sidnicious Farklı bir parametre alan bir sıralama yöntemine sahip olmak mantıklıysa. Örneğin public void Sort(bool sortByDescending = false), eğer yanlışsa, artan olarak sıralar. Veya mantık çok farklıysa sadece iki farklı sıralama yöntemi kullanın.
MattMcGowan

@Sidnicious, sıralama mantığı dışında her şeyi tek bir üçüncü modele devreten iki farklı modele sahiptir. docs.google.com/drawings/d/…
rightfold

62

Sıralama düzenini kim kontrol eder?

Basit MVC diyagramı( Wikipedia'dan )

1) Verilerin kendisinde doğal düzen:

Sipariş, Modelin bir parçasıdır, bu yüzden oraya gitmelidir. "Tüm verilerin" işlenmemiş bir şekilde çekilmesi, verileri sıralanmış düzende döndürür ve sıralama düzenini seçmek için bir arabirim yoktur.

2) Kullanıcı, verileri nasıl gördüğünü kontrol etmelidir:

Görünüm, Denetleyici ile etkileşime giren bir arabirim (artan / azalan oklar gibi) sağlar ve Model, verileri veriler üzerinde istenen sıralamayı yapacak kadar iyi anlar. Ancak, (1) 'in aksine, verilerin ham bir şekilde çekilmesi zorunlu olarak sıralanmak zorunda değildir.

Her iki durumda da,

Görünüm, bir tür devam ettiğini, diğerinin hangi sıralama yönünün seçildiğini gösterme yeteneğini anlamıyor. Mantığı oraya koymayın.

Küçük uyarı

Sıralama işlevi , yalnızca bir görünümde (hazırlıksız düşünebileceğim; daha fazlası olabilir), Görünüm'e gidebilir:

Tüm verilerin zaten görünümde olduğu ve sıralamayı yapmak için herhangi bir alan bilgisi kullanmak zorunda olmadığı bir "aptal" sıralama. Örneğin çok basit bir dize veya sayı karşılaştırması. Örneğin, sonuçların birden çok sayfaya bölünmesi muhtemel olduğunda, bir web sayfasındaki arama sonuçlarında bu mümkün değildir.


59
Görünüm kullanıcıyı görebilir !?
Farzher

41
Model görünümü günceller !?
deceze

13
Bu wikipedia makalesi berbat: "Bileşen etkileşimi" bölümü sağda gösterilen şema ile çakışıyor (burada az önce yayınladığınız). İkinci olarak, model görünümü "güncellemez". Durum değişikliği olduğunda görüşü BİLDİRİR. Görünüm nasıl güncelleneceğine karar verir. Ugh. Bu kadar net olmayan bilgi olduğunda neden bu soruya 1000 farklı cevap olduğunu merak ediyorsunuz.
KyleM

4
@cHao Tabii. Wikipedia grafiğinin oldukça garip olduğunu kabul edebiliriz, değil mi? :)
deceze

6
@StephenSarcsamKamenar ve diğerleri: Hayır, görüntü tam anlamıyla mantıklı: Kod bağlantılarını değil, veri akışını gösteriyor .
Izkata

18

MVC açıklamasına göre ,

Bir denetleyici, görünümün modelin sunumunu değiştirmek için ilişkili görünümüne komutlar gönderebilir (örneğin, bir belgeyi kaydırarak). Modelin durumunu güncellemek için modele komutlar gönderebilir (örn. Bir belgeyi düzenlemek).

Buna göre, sınıflandırma mantığı denetleyiciye aittir, çünkü model verilerinin sıralanma şeklini değiştirmek, "modelin görünümünün sunumunu değiştir" kategorisine girer.

DÜZENLEME: Yorumlarda dile getirilen birden fazla yanlış anlama açıklığa kavuşturmak için, "sıralama mantığı" sıralama yapan kod değildir ; sıralamayı tanımlayan koddur . Sıralama mantığı, bir sipariş oluşturmak (örneğin bir örneği aracılığıyla IComparator<T>) veya harici bir sistem (örneğin bir örneği aracılığıyla IOrderedQueryable<T>) siparişi için kullanılacak bir nesneyi oluşturan mantığı içeren tek tek öğeleri karşılaştırır . Bu mantık denetleyicinize aittir, çünkü uygulamanızın "iş" tarafı ile ilgili bilgiye ihtiyaç duyar. Sıralamayı gerçekleştirmek için tamamen yeterlidir, ancak gerçekte performans gösteren koddan ayrıdır.o. Sıralanan kod sizin görünümünüzde, modelinizde, hatta modelinizi destekleyen kalıcılık katmanında (örneğin, SQL veritabanınız) olabilir.


12
-1 Bunu bu alıntıdan nasıl çıkardınız? Denetleyicinin modelden bilgi alması gerektiği söylenen bir yer var mıydı? Denetleyici durumu değiştirmek için komutlar gönderir. Bilginin çıkarılması veya manipülasyonu hakkında söylenen hiçbir şey yoktur.
tereško

3
@ tereško Cevabımdan denetleyicinin modelden bilgi alması gerektiği sonucuna varmayı nasıl başardınız? "Sıralama mantığı" ile sadece bir sipariş oluşturmak için gerekli olan mantığı kastediyorum - C # terimleriyle, bunun bir uygulamasını sağlar IComparer<T>. Modelden verilerin alınması da dahil olmak üzere, geriye kalan "kazan plakası mekaniği" görünüme bağlıdır.
dasblinkenlight

3
“.. sıralama mantığı denetleyiciye aittir ..” , bu başka ne anlama geliyor?
tereško

3
"Bir denetleyici, görünümün sunumunu değiştirmek için ilişkili görünümüne komutlar gönderebilir", denetleyicinin komutuna yanıt olarak görünüm sıralamayı yapacak gibi görünür.
Samuel Edwin Ward

1
@KyleM Ancak görünüm her zaman sıralama mantığını içerecek kadar yeterli bilgiye sahip değildir. Örneğin, numaralandırmalardan birine karşılık gelen sayısal bir kodu olan bir alanı düşünün {Unknown, Pass, Fail}. Ayrıca Unknown, kullanıcının seçtiği artan veya azalan sıraya bakılmaksızın her zaman en son sıralanması gerektiğini varsayalım . Bu mantığın görünüme yerleştirilmesi, görüşünüze codealandaki verilerin iş yapısı hakkında çok fazla bilgi verir . Görünüm bunu bilmemelidir: tek bildiği, kullanıcının bir "sıralama" hareketi gerçekleştirmesidir (örneğin bir üstbilgiye tıklamak); gerisi denetleyiciye kalmış.
dasblinkenlight

10

Yukarıdakilerin hiçbiri. Sıralama iş mantığıdır ve iş mantığı üçünden hiçbirine ait değildir. Uygulamanızdaki her kod parçası bir model, görünüm veya denetleyici olmayacaktır.

MVC uygulamalarımda genel olarak yaptığım şey, tüm iş mantığını gerçekleştiren bir hizmet katmanım olması. Hizmet katmanındaki yöntemlerin, iyi adlandırılmış parametreleri olan temiz ve basit bir API'si olmalıdır. Daha sonra modellerde verileri değiştirmek için bu yöntemleri kumandanızdan çağırabilirsiniz.

Bu anlamda, sıralama "kontrolörde" dir, ancak sıralama yapan kodun kendisi kontrolörde uygulanmamalıdır, sadece oradan çağrılmalıdır.


5
Kısa süre önce, bazı kişilerin bir "hizmet katmanı" (iş mantığı) modelinin bir parçası olduğunu düşündükleri bildirildi.
Marvo

@Marvo Bazı mantık parçalarının veri türlerine bu kadar sıkı bağlı olduğu bazı durumlar olduğunu düşünüyorum, bunları bir sınıfta bir araya getirmek mantıklı. (örneğin saat ve tarih işlevleri). Genel olarak, model nesneleri veri tutmaktan başka bir şey yapmadığında en iyi sonucu veririm.
nont

Peki iş mantığı MVC modelinde nerede yaşıyor?
Marvo

2
Bir uygulamanın MVC kalıbı kullanması, uygulamadaki her kod parçasının bir model, görünüm veya denetleyici olacağı anlamına gelmez. Bu, tasarım kalıplarını tam anlamıyla alıyor. Örneğin, uygulamanız muhtemelen bir tür yapılandırma dosyasına sahiptir. Bu yapılandırma dosyası ne kullanıcı verilerini modelliyor ne de görünümler sunuyor ya da modellerden görünümlere veri akışını kontrol etmiyor. Kendi türünde bir yapılandırma dosyası.
nont

Biri, modelin bir yapılandırma dosyası bölümünü kolayca düşünebilir. Modelin veritabanı olması gerekmez. Doğru ya da yanlış olduğunu söylemiyorum. Sadece son zamanlarda yaptığım gibi (çünkü sahip olduğun aynı görünümü tuttuğum için) konuyu biraz google'a ve başkalarının ne söylediğini görmeni öneririm.
Marvo

8

Kesinlikle denetleyici değil: Görüntülemek ve modele mesajlar gönderir, ancak mümkün olduğunca az iş yapmalıdır. Kullanıcı, model veya görünüm hakkında bu durumu bildirerek, istek, denetleyici tarafından işlenen sıralamayı değiştirebilirse.

Belki de görünüm saf bir görünümse. Uygulama sıralama olmadan da iyi çalışıyorsa, sıralama temsilin bir parçasıdır ve görünümde gitmelidir.

Sipariş alan adının doğal bir parçasıysa, modelde yer almalıdır.


"Bir karşılaştırıcı veya bir tür tanımlayıcı sağlamak", "iş yapmak" olarak sayılır mı? Bir sıralama mantığı bir karşılaştırıcıya veya bir sıralama tanımlayıcısına kapsüllendiğinden, sıralama yönteminde veya modelin arka ucunda "sıralama işi" yapılmış olsa bile.
dasblinkenlight

Sağlayarak ne demek istediğinize bağlıdır: içeri girme tamam. Ancak Karşılaştırıcı, denetleyicinin değil modelin veya görünümün bir parçası olmalıdır.
Jens Schauder

6
  • Görünümler, MVC'nin sunum mantığını içerdiği düşünülen parçasıdır.
  • Model katmanı iş mantığının bulunduğu yerdir.
  • Kontrolörler kullanıcı girişine bağlı olarak her ikisinin de durumunu değiştirir.

Yani seçim - bunun etki alanı iş mantığının veya sunum mantığının bir parçası olduğunu düşünüyor musunuz?

Uygun bir MVC Model2 veya klasik MVC deseni uyguluyorsanız, model katmanı tarafından sağlanan verilerin sırasının, görünümün model katmanına isteği tarafından tetiklenmesi gerektiğini söyleyebilirim. Görünüm sipariş veri ister, model katman sağlar.

Ancak, ASP.NET MVC'nin standart MVC'nizden biraz farklı olan MVC desenini yorumladığınız için, ViewModel örneği model katmanından sipariş bilgileri istemelidir (bir nedenden dolayı ASP.NET çerçevesi şablonların çağrılması gerektiğini düşünür) "görünümler" ve görünümler "viewmodels" olarak adlandırılmalıdır .. garip).


12
"Sıralama mantığı" ile ne anlama geldiklerine dair kendi varsayımlarınızı uygulayarak birden fazla cevabı indirmeye devam ettiniz . Varsayımınız tamamen yanlıştır - sıralama mantığı geri alma işlemini içermez ve asla içermez.
dasblinkenlight

1
@dasblinkenlight, evet, hepsi denetleyicinin sıralama yapması gerektiğini ima ettikleri için birden fazla konuyu aşağı indirir. Hangisi yanlış. Ve .. insanlar .. lütfen katılmıyorum diye yorumlarımı işaretlemeyi bırak.
tereško

Açıkça söylemek gerekirse: Cevabınızı yanlış değerlendirmedim, çünkü yanlış değil ve yorumlarınızdan hiçbirini işaretlemedim, çünkü o zaman herhangi bir şekilde küfürlü olduğunu bulamıyorum. Dürüst olmak gerekirse, cevabınızın nasıl bu kadar çok oy almayı başardığını bilmiyorum: Sanırım kötü tasarlanmışlar.
dasblinkenlight

@dasblinkenlight naah .. Bu konuda yok olan yorumlarım hakkında çok şiddetliyordum.
tereško

5

Genellikle diğer cevaplara göre desenle aynı kalması için kontrolörde yapardım. Muhakeme için aşağıya bakınız.

Ben bu konuda mulling ve cevapları ve ilgili materyalleri okudum ve pragmatik olarak konuşursak, örneğin başvurunuza bağlı olacağını söyleyebilirim:

Orta / büyük bir uygulama mı ve / veya onunla ilişkili birden fazla kullanıcı arayüzü var mı (yani bir Windows Uygulaması, Web arayüzü ve Telefon arayüzü).

  • Bu durumda muhtemelen bir hizmet katmanı oluşturur ve iş nesnesine koyarım ve daha sonra denetleyiciden uygun yöntemi çağırırdım.

Bu iyi tanımlanmış tek bir UI web sitesi ve EF Kodu Önce gibi bir şey kullanıyorsanız ve bir hizmet katmanı oluşturma niyetiniz yoksa veya hiç niyetiniz yoksa ve bunu elde etmek için basit bir kutu uzantısı yöntemi kullanmayı planlıyorsanız:

  • Bu durumda muhtemelen kontrolör içine pragmatik olarak zaman / bütçe açısından en uygun olduğunu koyardım.

Yukarıdaki AMA ile aynı ise kutudan çıkma yöntemi ile uygulanamaz.

  • Ben de burada bir denetleyiciden daha uygun olacağı için Model sınıfında pop (eğer gerçekten bu tek tip ısmarladıysanız) seçebilirsiniz. Sıralama birden fazla sınıfa uygulanabilirse, bunu bir uzantı yönteminde uygular ve daha sonra denetleyicide çağırırdım.

Sonuç olarak:

Dogmatik cevap: Hizmet Katmanı

Pragmatik cevap: Genellikle denetleyici


Hangi tanım denetleyicisi "verileri görünüme hazırlamaktan" sorumludur?
tereško

1
@ tereško: Modelin burada belirtildiği gibi "pasif" olduğu yerlerde , varyasyonlar bölümünde msdn.microsoft.com/en-us/library/ff649643.aspx . Bkz. "HTTP bunun bir örneğidir". Bir saflık bunu tartışabilirken, MVC'den başlayan yeni başlayanlar için EF'yi veya diğer modelleri doğrudan kontrolörde kullanıyor olabilirler ve bu şekilde düşünmek için bir BAL aracılığıyla değil, modeli daha iyi anlama bariyerini düşürürler.
Luke Baughan

1
bahsettiğin şey "anemik model".
tereško

Dikkat edin, önerdiğiniz gibi rahatsız edici açıklamaları kaldırdım. Girdi için şerefe!
Luke Baughan

3

Bir açılan listede yararlı olacak kadar küçük bir tablo verilerinden veri sıralama önermek-zaten sorgu ile sıralanmış DB gelmelidir. Bana göre bu, modeli sıralamanın uygulandığı yer yapar.

El ile sıralama yapmaya kararlıysanız, mantık için tercih ettiğiniz nokta olarak modeli veya denetleyiciyi kullanmak için iyi argümanlar olduğunu düşünüyorum. Sınırlama sizin özel çerçeveniz olacaktır. Verileri yalnızca modelde yönetmeyi tercih ederim. Denetleyiciyi (kendi) öğrettiğim gibi veri (model) ve sunum (görünüm) ile evlenmek için kullanıyorum.


2

Prensipte sıralamanın Business Logic olduğu fikrine katılırken, kökenine göre parçalayarak "Müşteri, Ürün sayfasının tarihe göre sıralanmış resimlerle görüntülenmesini ister" gibi bir şeyle sonuçlanırsınız. veriler için sıralama düzeni genellikle keyfi değildir - hala ihmal ile bir işletme kararı olduğu için bir sıralama olmasa bile (boş bir liste hala bir listedir).

AMA ... Bu cevap ORM teknolojisindeki gelişmeleri hesaba katmıyor gibi görünüyor, sadece Entity Framework ile ilgili olarak konuşabilirim (bunun gerçek ORM olup olmadığı konusunda bir tartışmadan kaçınalım, asıl nokta bu değil) kullandığım şey bu, ancak eminim diğer ORM'ler benzer işlevsellik sunuyor.

MS MVC ve Entity Framework kullanarak bir Ürün sınıfı için Güçlü Yazılmış bir görünüm oluşturursam ve Ürün ve Görüntü tablosu (örn. görünüm sırasında görüntülerde böyle bir şey kullanarak görüntüler:

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

İş mantığımın% 80'ini gerçekleştirmek için kullandığım belirli bir İş Mantık katmanından bahsedildi, ancak İş Mantık katmanıma, kutudan çıkan bir şeyi taklit eden sıralama işlevselliği yazmayacağım Varlık Çerçevesinden.

Ben bu soruya doğru bir cevap olduğunu düşünmüyorum; mümkün olduğunda karmaşık iş mantığını soyutlamanız gerekir, ancak tekerleği yeniden icat etmek pahasına değil.


Aynı şeyi düşünüyordum, buradaki cevaplar ORM'leri ve Uzantı yöntemlerini dikkate almıyor gibi görünüyor. Çoğu durumda sıralama mantığı kadar basit olacaktır myList.OrderBy(x => x.CreationDate)- sadece bunu yapmak için gereksiz herhangi bir ekstra katman eklemeye gerek yoktur. Buna eklemek için, sayfalanmış ve sıralanmış verilere ihtiyaç duyarlarsa ne yapardılar? Tüm tabloyu sorgula, sırala ve sonra neye ihtiyaçları olduğunu koru? Biri sadece arayabilir myList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)ve gereksiz veri alınmaz.
Balázs

1

MVC web siteniz, WebForms web siteniz ve bir mobil uygulamanız olduğunu varsayalım.

Sıralamanın bu sunu katmanları arasında tutarlı olmasını istiyorsanız, sunu katmanının dışında sıralama söyleyebilirim. Hizmet iyi bir aday olacaktır.

Aksi takdirde, bu mantığı bir görünüm modelinde saklardım. Neden? Çünkü yeniden kullanılabilir ve kolayca test edilebilir.


0

Listelediğiniz üç kişiden, denetleyiciye ait olduğunu söyleyebilirim. Yine de, bu tür bir mantığı denetleyiciye yerleştirmeyi sevmiyorum. Genellikle denetleyicinin iletişim kurduğu ve veri deposuyla iletişim kurmaktan ve sıralama mantığını işlemekten sorumlu bir hizmet katmanı oluştururum. Küçük uygulamalar için kontrolörde oturmak iyidir.


2
Bu mantığı model tarafına daha fazla koyacaktı, değil mi?
Ryan Kohn

Evet, "hizmet katmanı" anlayışım modelin bir parçası.
Marvo

0

Bu, asp.net göz önünde bulundurularak sorulan bir sorudur, ancak birisi Rails'ten bahsettiği için, sorunu bu bağlamda düşünmenin ilginç olacağını düşündüm. Rails'te, çerçeve ve ActiveRecord / ActiveQuery api için öngördüğü için sıralamayı bir denetleyici eylemi olarak alma ile birlikte yapmak doğal ve oldukça yaygındır. Öte yandan, statik öğeler için bir tür özel sıralama düzeni tanımlamak ve denetleyici tarafından kullanılacak modele koymak mümkündür, böylece model, gerçekleştirilmese bile sıralama mantığında bir rol oynayabilir operasyon doğrudan. Her ne ise, sıralama mantığının görünüme konmasının genellikle kaşlarını çattığını söylemek güvenli olabilir.

Bazı cevapların kesinlikle denetleyiciye veya modele göre sıralamaya karşı olduğu konusunda biraz eğlendim ve onları zevkime göre çok bilgiç buluyorum, ancak bunun kullanılan çerçevenin doğasına ve ilgili olağan sözleşmelere bağlı olduğunu düşünüyorum. o. Ben de Bill K'nin ilk etapta ayrılığa sahip olmanın daha önemli olduğu yorumuna katılıyorum.

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.