Neden iş mantığını modele soktunuz? Birden fazla depolama türüne sahipsem ne olur?


70

Ben her zaman iş mantığının denetleyicide olması gerektiğini ve denetleyicinin 'orta' kısım olduğundan sabit kaldığını ve model / görüntünün arabirimler aracılığıyla ele alınması gerektiğini düşündüm. Bu şekilde iş mantığını başka hiçbir şeyi etkilemeden değiştirebilir, birden fazla Model (her veritabanı / depolama türü için bir tane) ve onlarca görünüm (örneğin farklı platformlar için) programlayabilirsiniz.

Şimdi bu soruyu , iş mantığını her zaman modele koymanız ve denetleyicinin görüşle derinden bağlı olduğunu okudum .

Bana göre, bu gerçekten mantıklı değil ve her seferinde başka bir veri tabanı / depolama türünü destekleme aracına sahip olmak istediğimde iş mantığı dahil tüm modelimi yeniden yazmam gerektiğini ima ediyor.

Başka bir görünüm istiyorsam, hem görünümü hem de denetleyiciyi yeniden yazmalıyım.

Birisi bunun neden olduğunu ya da bir yere yanlış gittiğimi açıklayabilir mi?

Yanıtlar:


69

ElYusubov'un cevabı çoğunlukla onu etkiliyor , etki alanı mantığı modele girmeli ve uygulama mantığı denetleyiciye girmelidir.

İki açıklama:

  • İş mantığı terimi burada oldukça yararsızdır, çünkü belirsizdir. İş mantığı, iş insanlarının umursadığı, bir veritabanında bir şeyi nasıl depolayacağı veya bir ekranda nasıl gösterileceği gibi sadece tekniklerden ayıran bir kavramdır. Hem etki alanı mantığı ("geçerli bir e-posta adresi ..." gibi görünüyor)) hem de iş akışları / iş süreçleri ("bir kullanıcı kaydolduğunda, e-posta adresini sormak"), ilk olarak açıkça ait olduğu şekilde model ve sonuncusu denetleyiciye giren uygulama mantığıdır.
  • MVC onunla etkileşime kullanıcıya ekranda şeyler koyarak ve izin için bir kalıptır, bu depolama belirtmez hiç . Çoğu MVC çerçevesi, yalnızca MVC'nin ötesine geçen tam yığın çerçevelerdir ve verilerinizi saklamanıza yardımcı olur ve depolanması gereken veriler genellikle modelde bulunduğundan, bu çerçeveler modelinizi saklamanız için uygun yöntemler sunar. Bir veritabanındaki veriler, ancak bunun MVC ile ilgisi yok. İdeal olarak, modeller ısrarcı olmalıdır ve farklı bir depolama türüne geçilmesi, model kodunu hiç etkilememelidir. Tam teşekküllü mimariler, bununla baş etmek için kalıcı bir katmana sahiptir.

4
Çoğu MVC çerçevesi, modellerinizi saklamanızı kolaylaştırmak için tüm depolama / veritabanı öğelerini modele karıştırır (genellikle çerçeveler model sınıfını genişletmenizi sağlayarak). Bu muhtemelen karışıklığın kaynağıdır. Teknik olarak, yazdığınız model kodunun asıl model (etki alanı katmanı) olması, oysa çerçevenin sağladığı kodun depolama (kalıcılık katmanı) ile ilgili olması gerekir. Örneğin, User.find (...) (Kullanıcı bir model olmakla birlikte) gibi bir şey çalışır, çünkü çerçeve Modelin bir parçası olarak depo desenini uygular.
Waquo

3
View-Controller-Model-Storage genel ilkedir (M, V ve C arasındaki ilişkinin bir üçgen olarak görselleştirilmesi gerekir). Çerçeveniz depolamayı "modeline" karıştırdığında, bu şekilde çalışır: View-Controller- (Model, depolamayı çerçeveden devralır).
Waquo

2
View-Controller-Model-Storage oldukça kaba, çünkü düz olmamalı. Örneğin, bir denetleyici model almak için User.find (...) gibi bir şey yaptığında, etki alanı katmanından geçmek yerine doğrudan depolama katmanını sorar.
Waquo

2
Daha dikkatli katmana sahip mimarilerde, UserRepository.find () gibi bir şey olur. "Model" derken, miras aldığınız çerçeve tarafından sağlanan "model" sınıfını kastettim. User.find () tarafından döndürülen Kullanıcı nesnesi, bir kullanıcının bir kullanıcının ne olduğunu, bir kullanıcının nasıl davranacağını modellenmesi anlamında bir kullanıcının modelidir ...
Waquo

1
@flipdoubt iş mantığı, bir uwp uygulaması söylemek için mvc'den taşınırsa aynı olması gereken herhangi bir mantıktır.
Andy

23

Siz ve programlama dünyasının büyük bölümleri, MVC bölümlerinin rollerinin ne olduğunu yanlış anlıyor gibi görünüyorsunuz. Kısacası, bunlar:

Model = etki alanı mantığı

Görünüm = çıktı mantığı

Kontrolör = giriş mantığı

Bu, modelin tüm işletme mantığından sorumlu olduğu anlamına gelir: bir ekran üzerinde widget çizmek, bir yazıcı kullanmak, HTML olarak veri çıkarmak, HTTP isteklerini ayrıştırmak vb. İle ilgili hiçbir şey modele dahil değildir.

Bununla birlikte, modern "MVC" çerçevelerinin çoğu MVC'yi gerçekten yapmaz veya parçalarını yanlış etiketler. Oldukça sık olarak, "model" olarak adlandırılan, modelin kalıcılık katmanıdır, iş mantığı ise "denetleyici" olarak adlandırdıkları yere oturur; Gerçek denetleyici genellikle yönlendirme tablosu içeren merkezi bir giriş noktası ve bireysel denetleyicideki giriş kodunu doğru iş süreçlerine göndermek için bir kod. Bu çerçevelerin "görünüm" dediği şey aslında her şeyin bir kısmı: bazı sunum mantığı (Görünüm), bir miktar girdi işleme ve doğrulama (Denetleyici) ve biraz daha fazla işletme mantığı (Model). Aslanın gerçek görünümdeki payına genellikle "şablonlar" denir.

Ayrıca Çok Katmanlı Mimari hakkında okumak isteyebilirsiniz; MVC'nin tek yönlü olduğu (akış Kontrolör -> Model -> Görünüm), Çok Katmanlı iki yönlü bir şeydir (Sunum -> Mantık -> Veri -> Mantık -> Sunum) ve çok az MVC yapıyormuş gibi görünen çerçeveler aslında Üç Katmanlı, Görme Sunumunu, Denetleyiciye Mantığı ve Veriyi Modelleme'yi yeniden etiketleyerek yapıyorlar.


2
Bence Modeli ("Model = etki alanı mantığı") yanlış tanıttığınıza inanıyorum, daha sonra MVC modelinin en saf haliyle bir Görünüm kullanılarak görüntülenen veriler için popülasyon için bir kap. Gerçekten basit kullanım durumlarında "etki alanı mantığı" olarak kabul edebileceğinizden emin olabilirsiniz, ancak varolan değere sahip sistemlerin çoğunun bu kadar hızlı sonuçlanacağına garanti ederim. "Etki alanı mantığını" ayrı bir katmana / sınıfa, örneğin bir hizmet katmanına bölmek daha iyidir.
A. Murray

@ A.Murray: Elbette Modelin tek yekpare bir kod bloğu olması gerekmez ve bunu kalıcılığa, veri yapılarına ayırmak ve etki alanı mantığı genellikle çok mantıklı olur. Yine de, MVC bu üç endişeyi Modelde bir araya getirir. Her durumda, denetleyicileriniz ve görünümleriniz etki alanı mantığı içerdiğinde, artık gerçek MVC değildir.
tdammers

@tdammers, cevabınızın düzenini ve mantığa odaklanmasını seviyorum. Sizce ısrar ve işlem işleme gibi uygulama kaygıları nerelere aittir? Görünüşe göre MVC, S'nin servis için olduğu MVCS gibi dört harften oluşan bir harf olmalıdır.
Flipdoubt'da

15

İş mantığını gerçekten izole etmek ve bunu sunum katmanı altyapısından ayırmak için uygulama hizmetleri tarafından kapsanmalıdır. MVC mimarisi, sunum katmanını uygulamanın bir yoludur ve tüm iş mantığını bu uygulama hizmetlerine devrederek bu kapsamda kalmalıdır. Görünüm modellerini görünüm ve üzerinde gösterilmesi veya okunması gereken veriler arasında bir bağdaştırıcı olarak düşünün. Kontrolör, iş mantığını barındıran görünüm modelleri, görünümler ve uygulama hizmetleri arasındaki etkileşime aracılık eder.

Uygulama hizmetleri, işletme kullanım durumlarını uygular ve MVC veya başka bir şey olsun, sunum katmanından ayrıştırılır. Buna karşılık, uygulama hizmetleri işlem komut dosyalarını veya etki alanı odaklı bir tasarımı barındırabilir .

Depolama için, uygulama servisi bir depoya veya bir kalıcılık mekanizmasının herhangi bir soyutlamasına başvurabilir . Veri erişiminin bir arayüze soyutlanmasıyla farklı uygulamalar desteklenebilir. Tipik olarak, bu soyutlamalar sızıntı yapar ve uygulamalar arasında sadece kısmen taşınabilir ve çoğu zaman tam taşınabilirliğe ulaşmak için boşuna bir girişimdir.

GÜNCELLEME

Benim önerim Altıgen mimarisine dayanıyor . Altıgen bir yapıda, etki alanı modeliniz (işletme mantığı) temeldedir. Bu çekirdek, cephe işlevi gören uygulama hizmetleri ile kaplanmıştır . Uygulama hizmetleri, etki alanınızdaki vakalara karşılık gelen yöntemleri içeren basit sınıflardır. Uygulama servisleri ile ilgili derinlemesine bir tartışma için Domain Driven Design'daki Servislere bakın . Kod örneği, PurchaseOrderServicebir satın alma alanı için bir uygulama servisi olanı içerir . (Bir uygulama servisinin alan odaklı tasarım kullanımı anlamına gelmediğini unutmayın.)

Altıgen bir yapıda MVC sunum katmanı, etki alanı modeliniz (işletme mantığı) ile bir GUI arasında bir adaptördür. Etki alanı modeli sunum katmanının farkında değil, sunum katmanı etki alanı modelinin farkında.

Bu çözüm kesinlikle, iş mantığını denetleyiciye yerleştiren bir çözümden daha hareketli parçalara sahiptir ve sakıncaları ve faydalarını ölçmeniz gerekir. Bunu önermemin nedeni, karmaşıklıkla mücadele etmek için iş mantığını sunum katmanından ayrı tutmayı tercih etmemdir. Uygulama büyüdükçe bu daha önemli hale gelir.


Hem denetleyicilere hem de modellere sahip olan bir MVC ve MVVM piçini tarif ediyor gibisiniz. Ayrıca, tarif ettiğiniz mimarinin OP'nin ihtiyaçları için biraz ağır olabileceğini düşünüyorum.
Waquo

dürüst olmak gerekirse, Waquo'nun cevabını daha çok seviyorum. Esas olarak, 'uygulama hizmetleri' ile ne kastettiğinizi hiçbir ipucum olmadığı için. Bu terimi açıklayabilir misiniz? GoogleFU’m burada göründüğü gibi çalışmıyor.
Steffen Winkler

1
@Ayrıca, önerilen mimarinin fazla abartılabileceğine katılıyorum, ancak göz önünde bulundurulması gerekiyor. Bir sunum katmanı uygulamanın başka bir yolu olan MVVM'den hiç bahsetmedim. Uygulama hizmetleri, MVC veya MVVM kullanıp kullanmadığınızdan bağımsız olarak uygulanır ve önerdiğim hiçbir şey bu ikisinin bir kombinasyonunu göstermez.
eulerfx

1

İş mantığı ile ne demek istediğine bağlı. Modelin içeriğine anlam veren herhangi bir "mantık", modelde olmalıdır. Bağlantılı soruda en yüksek oyu alan cevap, "iş mantığını" veriyle ilgili herhangi bir şey olarak tanımlamaktadır; Bu, bir işletmenin verilerinin onun işi olduğuna göre mantıklı geliyor!

Bir keresinde, tam olarak bu konuda devam eden Rails'in yaratıcısı tarafından bir örnek gördüm - modele "iş mantığı" koymak değil. Örneği, bir denetleyici sınıfı ve uygulama kaydı ve oturum açma için bir yöntemdi - düz metin olarak verilen bir parola, modele eklenmeden veya modele karşı sorgulanmadan önce şifrelenmişti (bir veritabanı).

Denetleyici mantığı olmayan ve doğrudan modele ait bir şeyin daha iyi bir örneğini düşünemiyorum.

Model, taşınabilirlik endişelerini azaltan sayısız veri deposuna bir arayüz olabilir. Model arayüzün aslında “kontrolör” olduğu konusunda burada kafa karışıklığı bulabileceğiniz biri var.

Genel olarak, denetleyici modeli ve görünümü birbirine bağlar (uygulamanın et ve patatesleridir). Kakao geliştirmede, denetleyicinin XCode GUI (denetleyici nesneleri ve ciltleri) üzerinden kullanıldığı noktaya basit olabilir.

GoF'un MVC'deki "Tasarım Desenleri" bölümü, gevşek bir şekilde alıntı yaptı:

MVC sınıf üçlüsü, Smalltalk-80'de kullanıcı arayüzleri oluşturmak için kullanılır. Model uygulama nesnesi, Görünüm ekran sunumu ve Denetleyici, kullanıcı arabiriminin kullanıcı girişine nasıl tepki vereceğini tanımlar. MVC, aralarında bir abone olma / bildirme protokolü kurarak görünümleri ve modelleri ayırır. Aşağıdaki şemada bir model ve üç görünüm gösterilmektedir. Basitlik için denetleyicileri dışarıda bıraktık.

MVC tamamen kullanıcı arayüzü ile ilgilidir. Odak, model üzerinde ve görünümde - verileri tanımlama ve gösterme. "Abone ol / bildir protokolünü" not edin - kontrol cihazınızın geldiği yer burasıdır. İstediğiniz tüm görünümleri oluşturabilirsiniz; Protokole bağlı kaldıkları sürece, modele veya kontrol cihazına asla dokunmanız gerekmez.

Özellikle web geliştirmeden bahsediyorsanız, IMHO birçok popüler web çerçevesi MVC terimi ve bileşen tanımları ile hızlı ve kayıtsızdır.


Ben bir C # / Java (sadece birkaç proje var) geliştiricisiyim. Görünüşe göre modelin ne yaptığını anladım. 'İş mantığını' kontrol ünitesine koymak gerçekten sadece bir sonuç oldu (düşünce trenim gitti) tamam, veri için model oluşturdum (okuma: veritabanı bağlantısı / depolama), bu nedenle iş mantığımın kontrol cihazına girmesi gerekiyor. Verileri veritabanına kaydetmeden önce uyguladım '. Sadece her şeyi kontrolörden bir seviye aşağıya taşımak zorundayım. Aslında, şu anda sahip olduğum bir sorunu çözüyor (bir programda MySQL ve MSSQL'i destekliyor)
Steffen Winkler

0

Neden bir servis katmanı tanıtmıyorsunuz?

Ardından denetleyiciniz daha yalın ve daha okunaklı olacak, daha sonra tüm denetleyici işlevleriniz saf eylemler olacak.

İş mantığını servis katmanında ihtiyaç duyduğunuz kadar çözebilirsiniz. Kodun tekrar kullanılabilirliği daha iyidir ve modeller ve depolar üzerinde etkisi yoktur.

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.