Bir MVC mimarisinde, Model ve Görünüm Kontrolöre ne kadar yakından bağlıdır?


16

MVC kullanan bir uygulamam var, ancak kontrolörün nasıl tasarlanması gerektiği konusunda biraz mücadele ediyorum. Örneğin, Görünüm aynı anda model verilerinin bazı alt kümelerini görüntülüyor. Ancak, bunun tam olarak nasıl ayarlanması gerektiğinden emin değilim. Örneğin, Görünüm veya Modelin Kontrolördeki işlevleri doğrudan çağırması normal midir? Bir çeşit arayüz üzerinden mi? Yoksa tamamen kapsüllenmişler mi ve Kontrolör veya birbirlerini hiç bilmiyorlar mı?

Sadece bir düzenleme olarak; Bu, herhangi bir web çerçevesinde yazılmayan özel bir uygulamadır, bu yüzden burada çerçeveye özgü ayrıntıları aramıyorum ve kendi seçimimi yapma özgürlüğüm var.


1
Cevap vermeyeceğim çünkü MVC mimarilerindeki deneyimim sınırlı, ancak duyduğum ve başkalarıyla konuştuğum her şeyden, M&V birbirine sıkı sıkıya bağlı, ancak C değil. M genellikle C ve V genellikle M.'nin bazı alt kümelerine veri verir
Steven Evers

8
@SnOrfus: Bu düşündüğümün tam tersi - M & V C ile birleşti ama birbirlerine değil.
DeadMG

1
Bu kadar çok cevap nasıl bu kadar yanlış olabilir. Burada MS'nin msdn.microsoft.com/en-us/library/ff649643.aspx
Reactgular

Yanıtlar:


15

Kontrolör aktivite akışını kontrol eder. Kullanıcı bu eylemi gerçekleştirir, denetleyici görünüm verilerini etki alanına iletir; bu, daha sonra yapılması gerekenleri yapar, yanıtlara dayanarak, denetleyici bir sonraki gösterilecek çerçeveye söyler (ve yapılması için yeterli veri verir) yani).

Böylece kontrolör bir dereceye kadar alan modeline bağlanmalıdır. yani. Araya bir hizmet katmanı koyabilirsiniz, ancak katı bir tanımla, alan adının bir parçası haline gelir.

Ayrıca görünüm verilerine de bağlıdır, ancak görünümün kendisine değil. yani. sadece "bu müşteri detayını kullanarak müşteri görünümünü göster" der. Çerçeve daha sonra bu görüşü nerede bulacağına karar verir.

Şimdi bu, aynı verilerin bir görünüm modelini kullanarak etki alanı modelini görünümden ayırmanıza izin vermelidir. Bazı geliştiriciler bunu yapıyor, bazıları yapmıyor ve bence bu büyük ölçüde kişisel tercih meselesi.

Rails'te, etki alanı nesnelerini (ActiveRecord) görünüme itmeniz ve görünümün bu erişimden faydalanmadığına (ör. Customer.save'yi çağırmamalısınız) kullanılabilir).

.NET dünyasında, gerçekleşmemesi gereken şeylere izin vermeyerek riski azaltma eğilimindeyiz ve muhtemelen bu nedenle, ayrılmış görünüm modelinin daha popüler olduğu görülüyor.


1
Birim modeli söz konusu olduğunda görünüm modeli çok yaygın bir uygulamadır. Normalde etki alanı modelini veya bir DTO nesnesini bir görünüm modeliyle otomatik olarak eşlersiniz. Daha sonra görünüm modelinizi bir görünümde kullanırsınız. Görünüm modeli kolayca test edilebilir ve aşağıdaki katmana bağlı değildir.
CodeART

7

Not: Robert C. Martin (diğer adıyla Bob Amca) bunu açılış konuşması Mimarlık Kayıp Yılları'nda çok daha iyi ve esprili bir şekilde açıklamaktadır . Biraz uzun ama çok iyi kavramlar öğretiyor.

tl; dr: MVC açısından uygulamanızı düşünmeyin ve planlamayın. MVC çerçevesi sadece bir uygulama detayıdır.

MVC ile ilgili en kafa karıştırıcı olan şey, geliştiricilerin yapıştırılmış tüm bileşenleri kullanmaya çalışmasıdır.

Çerçeve açısından değil, bir program açısından düşünmeyi deneyin.

Programınızın bir amacı var. Bazı veriler alır, verilerle işler yapar ve bazı veriler döndürür.

Bu şekilde, controllerprogramınızın dağıtım mekanizmasıdır.

  1. Bir kullanıcı programınıza bir istek gönderir (diyelim ki alışveriş sepetine bir ürün ekleyin).
  2. Denetleyici bu isteği alır (ürün bilgisi ve kullanıcı bilgisi), programınızın bu isteği işleyecek gerekli bölümünü çağırır $user->addToCart($product)
  3. Programınız ( bu durumda nesnenin addToCartişlevi user) yapmak istediği işi yapar ve bir yanıt döndürür (diyelim success)
  4. Kontrolör, ilgili olanı kullanarak yanıtı hazırlar view: örn. denetleyici nesnesinde$this->render($cartView('success')

Bu şekilde kontrolörler programdan ayrılır ve iletim mekanizması olarak kullanılır. Programınızın nasıl çalıştığını bilmiyorlar, sadece programın hangi kısmının talepler için çağrılması gerektiğini biliyorlar.

Başka bir çerçeve kullanmak istiyorsanız, uygulamanızın bir değişikliğe ihtiyacı yoktur, istekleriniz için programınızı aramak üzere ilgili denetleyicileri yazmanız yeterlidir.

Veya bir masaüstü sürümü yapmak istiyorsanız, uygulamanız aynı kalacak, sadece bir dağıtım mekanizması hazırlamanız gerekecek.

Ve Model. Bunu bir kalıcılık mekanizması olarak düşünün.

OO yolunda, programınızda verileri tutan nesneler vardır.

class User {
    //...
    private $id;
    private $shoppingCart;
    //...
}

class Product {
    //...
    private $id;
    //...
}

Eğer alışveriş sepetine ürün eklediğinizde, ekleyebilir product::idiçin user::shoppingCart.

Verileri kalıcı hale getirmek istediğinizde model, sınıfları veritabanı tablolarıyla eşleştirmek için çerçevenin genellikle bir ORM kullanarak oluşan kısmını kullanabilirsiniz .

Kullandığınız ORM'yi değiştirmek isterseniz, programınız aynı kalacaktır, sadece eşleme bilgileri değişecektir. Veya veritabanlarını hep birlikte kullanmak istemiyorsanız, verileri düz metin dosyalarına yazabilirsiniz ve uygulamanız aynı kalır.


Önce programınızı yazın. 'OO' yolu ile programlama yapıyorsanız, dilin düz eski nesnelerini kullanın. İlk başta MVC açısından düşünmeyin.


Harika video. Teşekkürler. Ama senin yorumuna katılmıyorum. MVC, Bob Amca'nın orada olduğu anlamında bir ayrıntı değil. MVC'nin kurduğu "Etkileşim / Varlık / Sınır" modeline çok benzeyen bir mimari model olduğunu göreceksiniz. Öte yandan, Spring veya herhangi bir şey gibi herhangi bir MVC sistemi gerçekten ertelemeyi önerdiği bir şeydir. Ancak açıkladığı gibi, "MVC" olarak adlandırılan bu çerçeveler bir tür terimin piç haline getirilmesidir.
Edward Strange

Evet, insanların a'nın ne olduğunu düşündükleri şekilde yazdım MVC. Bu yüzden yazdım MVC Framework.
Hakan Deryal


1

MVC'nin tipik bir Java Swing uygulamasında nasıl kullanılabileceğinin basit bir örneği ...

Diyelim ki bir Düğme ve bir TextField içeren bir Paneliniz var. Düğmeye basıldığında, uygulamada bazı durum değişikliklerine yol açan bir olay tetiklenir. Durum değişikliği kaydedildikten sonra TextField devre dışı bırakılır.

Bu basit bir MVC uygulaması tarafından alınan tipik bir yaklaşım olacaktır ...

Kontrolör kendisini View olaylarının dinleyicisi olarak kaydeder. Düğme tıklatıldığında, Görünüm'ün kendisi olayı işlemez; Denetleyici yapar. Kontrolör, Swing ile ilgili olaylarla ilgilenmesi gerektiği için Swing'e özgüdür.

Kontrolör bu bildirimi alır ve kimin işlemesi gerektiğine karar vermelidir (Görünüm veya Model). Bu olay uygulamanın durumunu değiştireceğinden, verileri veri ve program mantığından sorumlu olan Model'e iletmeye karar verir. Bazıları program mantığını Denetleyiciye yerleştirme hatasını yapar, ancak OOP'ta Modeller hem verileri VE davranışı temsil eder. Bunu yaparken Martin Fowler'ı okuyun.

İleti, Model tarafından uygun bağlamda alınır. Yani, Swing'e veya GUI'ye özgü diğer referanslara yapılan herhangi bir atıftan tamamen vazgeçilmezdir. Bu mesaj Model ve SADECE model ile konuşur. Modelde javax.swing ifadelerini içe aktardığınızı düşünüyorsanız, Modeli doğru şekilde kodlamıyorsunuz demektir.

Model daha sonra durumunu 'devre dışı' olarak ayarlar ve ilgili model değişikliklerini ilgili taraflara bildirmeye devam eder. Bu olayla ilgilenen Görünüm, kendisini zaten herhangi bir model değişikliğinin Gözlemcisi olarak kaydetmiştir. Model durumu değişikliği olayı Görünüm tarafından alındığında, TextField öğesini devre dışı bırakmaya devam eder. Ayrıca Görünüm'ün Denetleyiciden geçmek zorunda kalmadan doğrudan Modelinden Salt Okunur bilgi alması da yasaldır (genellikle bu tür etkinlik için Model tarafından maruz bırakılan belirli bir arabirim aracılığıyla)

Sunum ve İş Mantığı ile Veri Katmanları arasındaki bu gevşek bağlantıyı teşvik ederek, kodunuzun çok daha sürdürülebilir olduğunu göreceksiniz. Sistemler büyüdükçe MVC'ye yaklaşımınız da artacak. Örneğin, Hiyerarşik MVC genellikle alt sistemleri birbirine bağlamadan büyük kurumsal geniş sistemler oluşturmak için MVC triadlarını birbirine bağlamak için kullanılan bir uzantıdır


0

Birleştirme (kaçınmak istediğiniz sıralama) iki sınıf arasında karşılıklı bağımlılık içerir . Yani, bir Foo bir Çubuğa ve bir Bar da bir Foo'ya bağlıdır, böylece diğerini değiştirmeden birini değiştiremezsiniz. Bu kötü bir şey.

Bununla birlikte, BAZI bağımlılıklardan gerçekten kaçınamazsınız. Sınıflar birbirlerini biraz tanımalı, aksi takdirde asla iletişim kurmayacaklardı.

MVC modelinde, Kontrolör etki alanı Modeli ile sunum Görünümü arasındaki iletişimi kontrol eder. Bu nedenle, Kontrolör Modelden yapması gerekeni yapmasını isteyecek kadar bilgi sahibi olmalıdır. Denetleyici ayrıca, görünümü istemciye veya kullanıcılara sunabilmek için Görünüm hakkında yeterli bilgiye sahip olmalıdır. Yani, Model Kontrolörün her ikisine de bağımlılıkları vardır. Ancak, Görünüm Denetleyici olmadan mükemmel bir şekilde var olabilir - orada bağımlılık yoktur. Aynı şekilde, Modelin kontrolör üzerinde herhangi bir bağımlılığı yoktur - basitçe budur. Son olarak, Model ve Görünüm birbirinden tamamen ayrıdır.

Temel olarak, Kontrolör, Görünümü Modelden ayıran dolaylılık seviyesidir, böylece birbirlerini bilmek zorunda kalmazlar.


Ah - bu yüzden downvotes - yanlış yazdım. Kontrolcünün her ikisine de bağımlılığı vardı. D'oh!
Matthew Flynn

-5

Deneyimlerime göre, genellikle model sadece bir görüşe bağlıdır, belirli bir görüşe değil, genellikle bir gözlemci olarak ... eğer böyle bir bağlantı varsa.

Görünüm genellikle baktığı şeyle eşleşir, bu da mantıklıdır. Görüntülediği şeyden ayrılabilecek bir görünüm bulmak zor ... ama bazen kısmi bir bağlantıya veya bir şeye sahip olabilirsiniz.

Denetleyici genellikle her ikisiyle de eşleşme eğilimindedir. Bu aynı zamanda bir anlam ifade ediyor çünkü görevi olayları model değişikliklerine dönüştürmek.

Tabii ki, bu sadece gözlemlediğim bir eğilim ve herhangi bir spesifik örnek hakkında gerçekten bir şey söylemiyor.

MVC'nin ne olduğunu ve bağlantı ilişkisinin ne olduğunu anlamak için MVC'nin nasıl geldiğine bakmalısınız. MVC'nin oluşturulduğu ortam, iletişim kutuları oluşturabileceğiniz form öğeleri olarak "widget'ların" bulunmadığı ortamdı. "Görünüm" bir kutu ve bir şeyler çizdi. Metin görünümü, metin çizebilecek bir kutu olacaktır. Liste görünümü, liste çizecek bir kutudur. "Denetleyici", bu görünümde gerçekleşen UI sisteminden tüm fare ve klavye olaylarını aldı; "textChanged" veya "selectionChanged" etkinliği yoktu. Kontrolör tüm bu düşük seviyeli olayları alacak ve modelle etkileşim yaratacaktır. Model, değiştirildikten sonra görüşlerini bildirir; o zamandan beri bu ilişkiyi "gözlemci" olarak görmeye başladık ve

Bu, MVC modelinin özüdür. Bu tür düşük seviyeli UI programlama artık genel olarak yapılmadığından, MVC birçok farklı yönde gelişmiştir. Bugün bu isimle geçen bazı şeyler MVC gibi neredeyse hiç bir şey değildir ve gerçekten başka bir şey olarak adlandırılmalıdır. Yine de bir diyalog anlamında daha büyük bir nesneyle etkileşime giren bir bütün olarak kullanılabilir. Yine de çok daha iyi alternatifler var.

Temel olarak, MVC'nin çözmesi gereken her şey şimdi widget'ların içinde gerçekleşiyor ve artık kullanmak zorunda olmadığımız bir şey.


Daha iyi bildiğini düşünenler için:

http://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod

http://msdn.microsoft.com/en-us/library/ff649643.aspx

Eminim daha fazlası var ama bunlar sadece Google'da listenin en üstünde. Gördüğünüz gibi, model büyük ölçüde MANY uygulamalarındaki bir görünüm arayüzüne bağlıdır. Genellikle bir model gözlemlenebilir ve görüş bir gözlemcidir.

Ama neden gerçekler engel olsun ki ...

Başka bir yanıta gönderilmiş bir makale de ifadelerimi destekliyor:

http://martinfowler.com/eaaDev/uiArchs.html

İnsanlar tasarım endüstrisindeki HERKESİN yanlış olduğunu söylemeye devam etmek istiyorlarsa, sorun değil.


4
Bu kesinlikle yanlış. Bir model hiçbir zaman bir görüşe bağlı olmamalıdır! Bu görüş soyut veya bir arayüz olsa bile. Bir model sunumdan tamamen ayrılmalıdır!
Şahin

3
Cevap yanlış. Model bir görünüme veya denetleyiciye bağlı değildir.
CodeART

2
@Crazy Eddie Dediniz ki: "Deneyimlerime göre, model genellikle sadece bir görüşe, belirli bir görüşe değil, genellikle bir gözlemci olarak" Alıntı yapılan makaleyi okudunuz mu? Öyle görünmüyor.
CodeART

2
@Crazy Eddie: Crappy kod projesindeki birisinin ne yazdığı umurumda değil. Bu korkunç bir tasarım. Değişiklikleri dinlemek için bir gözlemci kullanmak uygundur, ancak bir etki alanı modeline sunum arabirimi koymak çok yanlıştır. Makalede belirtilen kod MVC ile ilgili bazı temel şekillerde kusurludur. Modelin dolaylı olarak kontrolöre bağlı olmasına bile izin verir. Ne saçmalık.
Falcon

3
@Crazy Eddie: lol @ downvote rampage. Seni öfkelendirdim mi?
Falcon

-7
  • Denetleyici modeli bir görünüme gönderir ve gönderilen modeli görünümlerden işler, ancak bir görünüme veya modele sıkıca bağlı değildir.

Denetleyici bir görünüme sıkıca bağlıysa, web formları dünyasında olacağız. Arkasında bir şablon dosyasına bağlanacak bir kodunuz olurdu (ASP.NET web formlarına uygulanabilir)

Bu nedenle, denetleyici bir modele veya görünüme bağlı değildir. Bu sadece istekleri işleme ve yanıt gönderme mekanizmasıdır.

  • Görünüm bir modele sıkıca bağlıdır. Modelinizde değişiklikler yapın (örneğin mülkünü değiştirin) ve görünümünüzde değişiklik yapmanız gerekir.

  • Model bir görünüme sıkıca bağlı değil. Bir görünümde değişiklik yaparsanız, model üzerinde hiçbir etkisi olmaz.

  • Model, kullanılabileceği denetleyici veya görünümler hakkında hiçbir şey bilmiyor. Bu nedenle model bir görünüme veya denetleyiciye sıkıca bağlı değildir.

Bunu düşünmenin başka bir yolu:

  • Bir denetleyicide değişiklik yapma - görünüm ve model etkilenmeyecek

  • Bir modelde değişiklik yapma - görünüm, bir modele bağlı olarak kesilecektir

  • Bir görünümde değişiklik yapma - model ve denetleyici bundan etkilenmeyecek

MVC projelerindeki bu gevşek bağlantı, onları ünite testini kolaylaştıran şeydir.


1
Bu çok yanlış, komik değil. Açıklamaya bile değmez. Sadece bu cevabı tamamen görmezden gelin.
Reactgular

1
@MathewFoscarini Ağlamayı kes ve "doğru cevap" bırak
CodeART

2
lol, MVC arkasındaki tüm tasarım teorisi, birbirlerine bağımlı olmamasıdır.
Reactgular

Sizin için daha fazla bilgi bıraktım, umarım mantıklı olacaktır
CodeART
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.