MVC anti OOP değil midir?


62

OOP'un arkasındaki ana fikir, veri ve davranışları tek bir varlıkta (nesne) birleştirmek. Prosedürel programlamada veri var ve verileri değiştiren ayrı algoritmalar var.

Model-View-Controller modelinde, veri ve mantık / algoritmalar sırasıyla model ve kontrolör olarak ayrı varlıklara yerleştirilir. Eşdeğer bir OOP yaklaşımında model ve kontrolör aynı mantıksal varlığa yerleştirilmemeli midir?


11
Neden aynı mantıksal varlık içinde olmaları gerekiyor? Bunun neden avantajlı olacağını veya OOP'nin bu düzenlemeyi neden diktiğini söylemediniz.
Robert Harvey,

26
İş mantığı denetleyiciye değil modele giriyor. Kontrolör, Görünüm ile Modeli birbirine yapıştırmak için gerçekten sadece bir adımdır. Yani modelde, aynı yerde veri ve davranış var.
Robert Harvey,

2
Ne? Verileri ve davranışı birlikte birleştirmek, OOP'un tam olarak ne hakkında olduğu ile ilgilidir.
Andy

3
OOP, uygulamaları arayüzlerden ayırmakla ilgilidir. Arayüzlerin davranışla daha fazla ilgisi var ve uygulamalar verilerle daha fazla (uygulamaların gizlenme eğiliminde olmasının nedeni) daha fazla. O halde, OOP veri ve davranışları birleştirmek değil, onları ayırmakla ilgilidir.
Kaz

5
Her neyse, tüm veri ve davranışları bir sınıfa sokmak istemezsin. OOP programları, nesnelerin çerçevelerini oluşturmak için birden fazla sınıfı kullanır. Her neyse, eğer bir şey "anti-OOP" ise, bu iyi bir şey olabilir. OOP hepsi sonuçta değildir. OOP düpedüz berbat. OOP'u yenmenin zamanı geldi.
Kaz

Yanıtlar:


45

MVC, UI mimarisi olan Endişelerin Ayrılmasında bir alıştırmadır . Sunumun içerikten ayrılmaması nedeniyle kullanıcı arayüzlerinde meydana gelebilecek karmaşıklığı düzeltmenin bir yoludur .

Teoride, tüm nesneler içerdikleri veriler üzerinde çalışan davranışlara sahip olabilir ve bu veriler ve davranış kapsüllenmiş kalır . Uygulamada, belirli bir OOP nesnesi, verisine karşılık gelen bir mantığa sahip olabilir veya olmayabilir veya hiç bir mantığa sahip olmayabilir ( örneğin, bir Veri Aktarım Nesnesi ).

MVC'de iş mantığı denetleyiciye değil modeline gider. Kontrolör, Görünüm ile Modeli birbirine yapıştırmak için gerçekten sadece bir adımdır. Yani modelde aynı yerde veri ve davranış olabilir.

Ancak bu düzenleme bile katı veri / davranış kaynaşmasını garanti etmemektedir. Yalnızca veri içeren nesneler, yalnızca mantığı içeren diğer sınıflar tarafından çalıştırılabilir ve bu, OOP'nin tamamen kabul edilebilir bir kullanımıdır.


Size özel bir örnek vereceğim. Bu biraz tartışmalı, ancak diyelim ki bir Currencynesneniz var ve bu nesnenin dolara sabitlenmiş herhangi bir para biriminde kendini temsil etme yeteneği var. Yani gibi yöntemler olurdu:

public decimal Yen { get { return // dollars to yen; } }
public decimal Sterling { get { return // dollars to sterling; } }
public decimal Euro { get { return // dollars to euro; } }

... ve bu davranış, Para birimi nesnesiyle kapsüllenir.

Ancak para bir hesaptan diğerine para transferi yapmak ya da biraz para yatırmak istersem ne olur? Bu davranış aynı zamanda Para Birimi nesnesinde de kapsanır mı? Hayır olmaz. Cüzdanınızdaki para, cüzdanınızdan banka hesabınıza geçemez; Bu parayı hesabınıza aktarmaya yardımcı olması için bir veya daha fazla acenteye (bir para çekme veya ATM) ihtiyacınız vardır.

Böylece bu davranış bir Tellernesnenin içine alınacak Currencyve Accountgirişler olarak kabul edecek ve nesneleri kabul edecektir , ancak Transactiongiriş nesnelerinin işlenmesine yardımcı olmak için belki biraz yerel durum (veya bir nesne) dışında herhangi bir veri içermeyecekti .


Ve hangi varlık / pakete Telleryerleştirilmeli? In Controlleryerden Teller'syöntemler denir veya Modeliş mantığının bunun nedeni kısmen?
m3th0dman

TellerModelkontrolörden aranabilmesine rağmen içeri girer . İş alanının bir parçası.
Robert Harvey,

Modelin iş kuralları için kullanılmasının MVC'yi yarı etkili bir model haline getirdiğini her zaman düşündüm. Modelin gerçek uygulamaya adaptörler için kullanılması ve kontrol cihazlarının adaptörler ve görünüm arasında arabuluculuk yapması, SoC'ye ulaşmada her zaman çok daha etkilidir.
Yam Marcovic

@YamMarcovic: Ne demek istediğinden emin değilim. Model, her şeyden önce bir çeşit; Uygulamada, işletme kuralları genellikle kendi hizmet katmanlarına yerleştirilir, ancak Modelin bir parçası olarak kabul edilir (örneğin, belirli bir iş kurallarını tek bir denetleyici yönteminde kodlamazsınız). Kontrolörlerin bir arada olduğu konusunda haklısın.
Robert Harvey,

5
Bir çok insanın MVC hakkında sadece okumaya başladığını düşündüğü bir şey, "iş mantığının" ne anlama geldiğiyle ilgili aşırı geniş varsayımlar olduğunu düşünüyorum. Modelinizi ortaya çıkaramaz ve tamamen aynı uygulama hedeflerine sahip, ancak tamamen farklı bir uygulama mantığı olan bir kontrolör aracılığıyla çok farklı bir mimariye sahip olan yepyeni bir uygulamada hiç bir değişiklik yapmadan kullanamazsanız, yanlış yapıyorsunuzdur. IMO. Elbette sahip olduğunuz herşeyin karışımından elde ettiğiniz görüntülerin ayrışmasına hala değer var, elbette ama hafif bir yapı olarak C, önemli bir ayrılma noktasını kaçırdığım için beni vurur.
Erik,

73

MVC , tekli nesnelerden çok daha yüksek bir soyutlama seviyesinde çalışır ve aslında üçünün her biri (model, görünüm ve denetleyici) tipik olarak her birinin hem veri hem de davranışa sahip olduğu birçok nesneden oluşur.

Verileri ve davranışları içine alan nesnelerin, genel olarak programlar için iyi bir temel yapı taşı olduğu, soyutlama seviyelerinin ve tüm amaçların en iyi modeli olduğu anlamına gelmez.


Nesneye yönelik yaklaşım, soyutlama düzeyinde ölçeklenebilir; örneğin klasik katmanlı mimari OOPish değil, prosedürsel olduğu için ortaya çıkan Domain Driven Design'ın arkasındaki nedene bakınız. Bu, MVC'den daha yüksek bir soyutlama seviyesinde gerçekleşir.
m3th0dman,

6
@ m3th0dman: Geniş, geniş genellemelerde konuşuyorsunuz. MVC'nin Winforms veya Webforms olan spagetti kodu kabusunu nasıl ortadan kaldırdığı gibi özellikleri tartışmaya ne dersiniz?
Robert Harvey,

3
@ m3th0dman: DDD'nin oldukça basit bir karakteristiği.
Michael Borgwardt

1
@RobertHarvey MVC'nin neden iyi olduğundan emin olun çünkü spagetti ile uğraşmıyor çünkü burada gerçekten yarışmada yer almıyor. Katılıyorum, ancak MVC'nin prosedür modelinde de uygulandığını görüyorum. Bu yüzden sormak için ilgili bir soru veya belki de sorulması gereken soru "insanlar MVC'yi prosedürel olarak ne sıklıkta uyguluyorlar?"
Jimmy Hoffa

1
@Robert Harvey Sorunun amacı MVC'nin ne kadar iyi ya da kötü olduğu ile ilgili değildir; OO prensiplerine dayanan veya dayanmayan bir gerçektir.
m3th0dman

71

OOP, her birinin kendi verisine ve davranışına sahip olan nesneler arasındaki etkileşimi kısıtlamaz.

Bir karınca ve karınca kolonisi analojisini düşünün: bireysel bir karıncanın davranışı (bütün gün koşuşturma, yiyecek getirme) genel koloninin davranışından farklıdır (en çok istenen yeri bulun, daha fazla karınca yapın). MVC paterni, bir karınca kolonisinin istenen sosyal yapısını tarif ederken, OOP bireysel karıncaların tasarımını yönlendirir.


5
+1: Genelde analojilerden yapılan açıklamalardan hoşlanmıyorum, ancak bu harika.
Michael Borgwardt

@Caleb Bu mükemmel bir nokta, çok teşekkür ederim!
dasblinkenlight

19

OOP ayrıca endişelerin ayrılması ile ilgilidir , yani farklı nesnelerdeki farklı rolleri / sorumlulukları ayırmaktır.

MVC bu bileşenlere ayrılır:

  • Model: veri ve iş mantığı
  • Görünüm: verilerin temsili
  • Denetleyici: model ve görünüm arasında koordinasyon.

Dolayısıyla bu sorumluluklar açıkça belirgindir ve gerçekten de çoklu varlıklara ayrılmalıdır.


Tek sorumluluk prensibinin OOP'yi etkili bir şekilde kullanmada yardımcı olduğu doğrudur, ancak bence "OOP da Tek Sorumluluk Prensibi ile ilgilidir" demek zor. Bu geriye görünüyor.
Caleb,

@Caleb Evet, ne demek istediğini anlıyorum. Belki de yeniden ifade edilebilir, ama sen anladın.
marco-fiset

18

Model-View-Controller modelinde, veri ve mantık / algoritmalar sırasıyla model ve kontrolör olarak ayrı varlıklara yerleştirilir.

Model ve denetleyici iki ayrı roldür. Bir modelde hem durum hem de mantık vardır ve bir denetleyicide hem durum hem de mantık vardır. İletişim kurmaları gerçeği ikisinin de kapsüllenmesini bozmaz - denetleyici , modelin verilerini nasıl sakladığını veya denetleyici bir kısmını aldığında veya güncellediğinde verilere ne yaptığını bilmez veya önemsemez . Model, kontrol cihazının modelin sağladığı verilerle ne yaptığını bilmiyor veya umursamıyor.

Bunu şu şekilde düşünün: nesneler enkapsülasyonu bozmadan ileri ve geri veri iletemezse, gerçekten tek bir nesneye sahip olabilirsiniz!

Eşdeğer bir OOP yaklaşımında model ve kontrolör aynı mantıksal varlığa yerleştirilmemeli midir?

MVC olan bir OOP yaklaşımı - özellikle, etkili bir program organize etmek nesneleri nasıl kullanılacağına karar için bir reçete bulunuyor. Ve hayır , model ve kontrolör aynı varlık olmamalıdır. Bir denetleyici, model ve görünüm arasında ayrılmaya izin verir. Modelin ve görüşün birbirinden bağımsız tutulması, onları hem test edilebilir hem de tekrar kullanılabilir hale getirir.


Kontrolörün mantığa sahip olduğunu ancak çok az ya da hiç devlet olmadığını umuyorum. Denetleyicinin ne tür bir durumu olduğunu düşünüyorsun?
Matthew Flynn

1
@MatthewFlynn Yeni başlayanlar için, bir denetleyicinin görünümü ve modeli bilmesi gerekir. Bunun ötesinde, bahsettiğimiz MVC'nin hangi özel lezzetine bağlı olabilir, ancak genel olarak bir kontrol cihazı bilginin nasıl gösterilmesi gerektiği ile ilgili durumu koruyabilir (örn. Mevcut seçim), oysa ki model hangi bilgilerin sergilendiği ile ilgilidir.
Caleb

1
@MattFenwick 'Lezzet' ile kastettiğim şey bu ... Kontrol cihazında tam olarak sakladığınız ve modelde ne olduğu bir zevk ve kongre meselesi. Cocoa / Cocoa Touch'ta kontrol ünitesinde geçerli seçim ve hatta kullanıcı tercihleri ​​gibi şeyleri saklamak yaygındır. Bazı web çerçevelerinde kullanılan MVC, modeldeki hemen hemen her şeyi ve denetleyicinin çok azını yerleştirebilir. YMMV.
Caleb

4
@MatthewFlynn Çoğu sizinle aynı fikirde olacaktır, ancak IMO, insanlar iş mantığını olması gerekenden daha geniş bir kategori olarak kabul ediyorlar. Kontrolör, insanların genellikle iş mantığı ile karıştığı uygulama mantığını ele alır. Kaygıların ideal bir şekilde ayrılmasında, bir işletme nesnesinde herhangi bir değişiklik yapmadan aynı işletme hedeflerine hizmet eden tamamen farklı bir uygulama mimarisinde bir model nesnesini yeniden kullanabilmeliyim. Yeni uygulamanın yapması gereken tek şey arayüzü kullanmak ve veri ve işlemlerle iade edilen ve işlenen işlemleri yapmaktır.
Erik,

1
@MattFenwick: Çok kullanıcılı uygulamayı düşünün. Model ve kontrol cihazı arasındaki çizgiyi çizmenin açık bir noktası, modelin ortak durumu ve kontrolörün yerel durumu ele almasıdır. Geçerli seçim yerel olduğundan denetleyiciye gider.
Jan Hudec

4

MVC, nesnelerin etkileşime girmesinin mantıklı bir yolunu tanımlayan bir kalıptır; bu bir meta sınıf değildir. OO, OO varlıkların davranışlarını ve verilerini ve söz konusu varlıkların nasıl etkileşimde bulunduğunu tanımlamakla ilgilidir. Tüm sistemi büyük bir nesnede birleştirmekle ilgili değil.


2

Denetleyici, bir modelin davranışını temsil etmiyor. Kontrolörler tamamen bir kullanıcının yapabileceği ve bir kullanıcının görebileceği tüm uygulamanın davranışını temsil eder.

Denetleyicileri ve modelleri tek olarak görmek yanlıştır. Farklı amaçları, farklı semantikleri var ve bu nedenle tek bir nesnede birleştirilmemeleri gerekiyor.


2

Model katmanı, yalnızca denetleyici katmanından yalnızca veri değil, yalnızca mantıktır.

Denetleyici katmanı, amaçları doğrultusunda eksiksiz bir nesne koleksiyonuna sahip olacaktır. Görünümden girdi almak ve bu girişi modelin işleyebileceği bir forma dönüştürmek için nesneler olacaktır. Struts Java çerçevesi, Eylem / Form modelinde buna iyi bir örnektir. Form, kullanıcıdan gelen girdilerle doldurulur ve ardından Faaliyete geçirilir. Eylem bu verileri alır ve modeli işlemek için kullanır.

Aynı şekilde, Model katmanı tamamen verilerden oluşmaz. Örneğin, bir Kullanıcı nesnesini alın - bir kullanıcıyı bir veritabanından alan koda ihtiyacınız olabilir veya bir Kullanıcıyı bir Sipariş ile ilişkilendirmek veya Kullanıcı adresinin şirket hizmet alanınız içinde olduğunu doğrulamak için kod gerekebilir ... resim. Bu kontrolör mantığı değil. İş mantığıdır ve Model katmanını, iş mantığı için Servis veya Yönetici katmanları, veritabanı erişimi için bir DAO (Veritabanı Erişim Nesnesi) katmanı ve diğerleri gibi birkaç katmana bölmesine yol açar.

MVC, bireysel Model işlemlerini organize etmek için bir yöntem değildir. Bundan daha yüksek bir düzeyde çalışır - uygulamaya nasıl erişileceğini organize etmek için bir yöntemdir. Görünüm, verileri işlemek için veri ve insan eylemleri sunmak içindir, Kontrolör, kullanıcı eylemleri ve çeşitli görüşler arasında çeviri içindir ve Model, iş verilerinin ve bunun iş nedenlerinin var olduğu yerdir.


2

OOP'nin amacı, birbirine ait veri ve işlevleri bir araya getirmektir . Bazı verilere dayanan bir hesaplama her zaman bu verilere ait değildir .

MVC'de bir veri parçasını (görünüm) görüntüleme işlevi veriden (model) ayrı tutulur. Neden? Özellikle ekran mantığının altında yatan verileri değiştirmek zorunda kalmadan değiştirilebilmesi için. Aynı verilerin farklı bir sunumunu yapmanız gerektiğinde görünümü değiştirmeyi kolaylaştırır: veya ekran donanımının özellikleri değiştiğinde: veya Windows'tan Linux'a geçtiğinizde; veya iki kişinin aynı verilere bakmanın iki farklı yolunu bulmasını istediğinizde.

MVC, OOP ile çatışmaz - aslında Nesneye Yönelik İlkelerin doğru bir şekilde uygulanmasından kaynaklanır.


0

Bir model nesnesine bağlı kalıcı verileri, modelin etkileşimde bulunduğu veritabanlarındaki uygulama verileriyle karıştırdığınıza inanıyorum. Bir model, iş mantığı ve veritabanlarıyla çalışma ve işlem yapma kuralları içerir. Bugün bir satış olup olmadığı, kullanıcının VIP statüsüne hak kazanıp kazanmadığı ve ardından verilere erişme, ayarlama veya işleme zamanı geldiğinde veya bir satın alma işlemi gerçekleştirme zamanı geldiğinde buna göre şube mantığı belirleyebilir ve kontrol edebilir. Nesneleri bir dizi yöntemin kapsüllenmesi ve kalıcı değerler veya veriler açısından tartışırken bahsettiğimiz bayraklar.

Model nesnesinin hangi iş kurallarının geçerli olduğunu belirlemeye yönelik verileri tutması gibi, bir kontrolör, IMO da, kullanıcının giriş yapmış olması veya geçerli bir kredisine sahip olmaları gibi, uygulamanın nasıl davranması gerektiği ile ilgili daha genel uygulama durumu verilerini tutmalıdır kart verileri yerinde. Model metotları, bunların ilk etapta durumunu belirleyecektir, ancak işletmenin nasıl yürüdüğüne veya veri işlemlerinin gerçekleştirildiği durum için geçerli değilse denetleyicinin genel uygulama akışına uygun bayrakları tutması mantıklıdır. Giriş yapmadıklarını belirledikten sonra, başka bir giriş yapma girişimi yapılıncaya kadar modeli kullanıcı kontrolleri ile bile rahatsız etmeyin.

Aynı şekilde, çoğu sunucu tarafında web çerçevelerinde gördüğünüz daha tipik HTML şablonlarına karşı uygun bir görüntüleme nesnesiyle. Kullanıcının renk tercihleri ​​yüklendikten sonra, bu verileri tutan ve üzerinde çalışan görünüm olmalıdır. Ayarların yüklenmesi, doğrulanması ve değiştirilmesi tüm model problemleridir, ancak değişiklikler gerçekleşene kadar sadece bir kez model problemleri olmalıdır.

IMO, hiçbir şey denetleyicilerin dahili toplama nesneleri olarak görüntüleyen ve modellerini birleştiren nesneler olamayacağını söylüyor. Bu, aslında MVC'yi bir UI widget fabrikası gibi daha küçük bir ölçekte uygularsanız mantıklıdır, çünkü denetleyici, Görünümü ve Modelin nasıl etkileşime girdiğinin verilerini ve mantık ayrıntılarını gömerken bir üst seviyedeki uygulama nesnelerine bir arabirim göstermek için ideal bir yerdir. Kontrolörün gerçekten de en üst seviye nesne olduğu monolotik uygulama nesneleri için anlam ifade etmiyor.


0

Anladığım kadarıyla; Argüman OOP'ye karşı bileşen tabanlı mimaridir. Ve dini savaşa girmeden, ikisinin de aynı şeyi tarif ettiğini düşünüyorum; sadece farklı açılardan bakıyorum.

Örneğin, OOP / OOD'un tüm amacı, kodunuzu daha modüler ve tekrar kullanılabilir hale getirmektir. Evet?

Tam olarak bileşen tabanlı mimarinin amacı budur. Yani onlar her şeyden daha benzerler.

MVC'nin sadece OOP'nin doğal evrimi olduğunu düşünüyorum ve söylemeye cüret ediyorum; nesnelerinizi düzenlemenin, endişelerin ayrılmasının ve kodun yeniden kullanılmasının daha iyi bir yolu.


MVC ve Bileşen Tabanlı Mimarinin, OOP yaklaşımlarının dışında olmayan tasarım desenleri olduğunu söyleyebilirim. OOD / OOP, sınırlayıcı bir her yerde programlamanın nasıl kullanılacağına dair bir sürü karışıklık ve düşünce ve malacademia okulunun çatışması düzgün bir şekilde inşa etmek. İki kategoriyi karşılaştırmak, kareleri ve kareleri çizmek için kullandığınız kalemi karşılaştırmak gibidir.
Erik,

-1

Bu partiye geç kaldım ve benimkilerden önceki tüm cevapları göz önünde bulundurarak, teklif edebileceğim çok şey olmadığını itiraf ediyorum. Fakat bana öyle geliyor ki, sorun kalıbın kendisiyle değil uygulama ile ilgili. Kendisi için MVC, herhangi bir özel metodolojiye kendisini ödünç vermez. Aslında, bir MVC düzeninde yordam yönelimli kodu kolayca düşünebilirim (bu, sizin ima ettiğim şey gibi).

Yani asıl soru şudur; MVC şablonunu kullanırken prosedür koduna daha yatkın mıyız?

(ve belki sadece biraz aşağı oy alacağım?)


-1

Anti-değil, aynı zamanda MVC için OOP gerekli değildir.

Çünkü genellikle sınıf tarafından temsil edilen kontrolörler veri içermemektedir. Hangi saf fonksiyonların yeterli olacağı.

Verileri daha ileriye götürür ve davranışlardan ayırırsanız, örneğin, modellerin yalnızca işlevlerini (veri manipülasyonundan sorumlu olan) her çağrışında toplanan veritabanı verilerinde çalıştığını varsayalım (bunun yerine örnekte bir tür veri depolamak için) alanlar) - o zaman modeller için aynı şeyi söyleyebilirsiniz.

Daha da ileri, bir uygulamanın görüş katmanını alır ve benzer şekilde bölerseniz, aslında MVC'nin OOP ile ilgisi olmadığı sonucuna varacaksınız ve MVC uygulamasının sadece prosedür yaklaşımı kullanarak herhangi bir acı çekmeden yazması tamamen mümkündür. .


Haha, bazı insanların gerçeklerle karşı karşıya kaldıklarında acı çektiklerini görüyorum. OOP ile kendi çerçevelerini oluşturmak için çok fazla çaba? Kayıp zamana dayanamıyor musunuz? En basit cevaplar en iyisidir.
luke1985

Bu cevabın neden aşağı oy verdiğinden emin değilim. İlişkili olmadığını ve "anti" olmadığını söylüyor. Oldukça doğru görünüyor.
mwilcox

-3

Görüşümde OOP'ların bir dezavantajı var ki (veri ve davranış) tek bir varlık olarak (Sınıf) biçimlendirildiğinden, bu uyumdan ziyade birleştirme etkisi göstermektedir. Öte yandan, MVC modelinde ... (Fasulye, DAO'lar, Diğer Mantık sınıfları) içeren, Kontrolün nasıl hareket etmesi gerektiğini belirten Kontrolör ve verinin nasıl gösterilmesi gerektiğini belirlemek için Görünümler ayrı bir şekilde verilmiştir. Buna bağlı olarak, proje hazırlamak için çok büyükse, OOP'lerin aksine karışık olmaktan ayrı bir varlık olarak kolayca yapılabilir. Problem, bölme stratejisi gibi mantıksal bir şekilde çözülür ve MVC bunu en çok takip eder.


Bu sadece senin fikrin mi yoksa bir şekilde mi destekleyebilirsin?
tatarcık
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.