MVC'de bir API isteğini nereye koymalıyım?


25

MVC deseni kullanarak bir web uygulaması yapıyorum. Bu tür bir mimarinin ardından veritabanı ile etkileşimde kullanılan tüm yöntemlerin modelde uygulandığını görebiliriz .

Ancak başkalarının maruz bıraktığı bir hizmeti web üzerinden aramak zorunda kalırsam ne olur? Örneğin, sayfamın tüm takipçisini alabilmek için Facebook API’ya erişmek istiyorum, öyleyse bu yöntemleri nereye koydum?

Açıkçası, görüş iyi bir fikir değil çünkü bu modül sunuma adanmış, kontrolör veri almak için kullanılmamalı, ancak model genellikle sadece veritabanı ile etkileşime adanmıştır.

Peki, bu konuda bana biraz ipucu verebilir misiniz? Ve lütfen, MVC mimarisiyle ilgili bazı hatalar yaptığımı söyleyebilir misiniz?


2
MVC başvurunuzu desteklemek için kullandığınız bazı kütüphaneleri ve çerçeveleri listelerseniz, insanların daha iyi cevaplar sağlayabileceğini düşünüyorum. MVC paterni teknoloji agnostik olsa da, tüm çerçeveler açıkça onu takip etmez. Dahası, çoğu olgun çerçevede zaten olağanüstü belgeler mevcut ve hangisini kullandığınızı bilmek sizi düşünme yönünüzü izleyen önceden var olan bir açıklamaya yönlendirmeyi kolaylaştıracak.
CLW

2
Veritabanı? Veri kaynağı? Onun sadece veri.

2
"MVC" nin ne olduğu konusunda çok fazla görüş var, bu sorunun cevaplanamayacak kadar soyut olduğu.
RemcoGerlich

2
Ayrıca, API'yi ön uç Javascript kodunuzdan çağırmayı ve arka uç "MVC" öğelerinize dokunmamasını sağlayın.
RemcoGerlich

@Remcogerlich bu yüzden bakmakta olduğu gerçek uygulamanın bir ekini önerdim. Bir arka uç ve mvc ön uç uygulamasıyla ilgileniyor olabilirdi. Bu farklılıkları daha iyi açıklayabilecek başka bir düzende olabiliriz.
CLW

Yanıtlar:


37

Model veri tabanı ile etkileşimi ile sınırlı değildir, model veriyi almak ve değiştirmekle sorumludur.

Bu nedenle, bakış açınıza ve kontrol biriminize göre, veriler bir veritabanından veya bir web servisinden geliyorsa veya hatta tamamen rastlantısalsa bile, hiçbir fark yaratmamalı, bu nedenle bunu modelde yapmalısınız.

MVC, yalnızca farklı temsil katmanlarını ayıran bir sunum düzenidir.

Bu, modelin tek tip bir spagetti kodu karmaşası olması gerektiği anlamına gelmez. Modeliniz kendisi de katmanlı olabilir, ancak kontrolör verilerin nereden geldiğini bilmemelidir.

Modelinizdeki genel bir yöntem, denetleyiciniz tarafından çağrılabilen şu şekilde (Sözde kod) yapılandırılabilir:

public MyDataClass getData(int id) {
    WebServiceData wsData = WebService->getData(id);
    DatabaseData dbData = ORM->getData(id);
    return new MyDataClass(wsData, dbData);
}

WebServiceve ORMbağımlılık enjeksiyonuyla sahte olarak değiştirilebilecek olan arayüzlerin örnekleri olması gerekebilir, ancak kontrolörleriniz ve görüşleriniz test amacıyla değişmek zorunda değildir.


8
Modelin herhangi bir mantığı olmamalı ve bu nedenle doğrudan hiçbir şey ile etkileşime girmemelidir. MVC modeli açıkça tüm mantıkların kontrol cihazlarına yerleştirilmesini gerektirir. Bu kontrolörler DB, API vb. İle bağlantı kurmalı ve modeli gerektiği gibi güncellemelidir. Bu, model teknolojinizi agnostik tutar ve ek manipülasyon için sunum ve kontrolörler için çeşitli görünümlere aktarılabilen bir depolama mekanizmasından başka bir şey olarak hizmet etmemesini sağlar.
CLW

3
@CLW: Model! = Veri modeli. Daha fazla ayrıntı başka bir yerde bulunabilir, örneğin stackoverflow.com/a/14045514/124983
Residuum

2
@CLW: iş mantığı M, V veya C'de olmamalıdır . Modeller bir veri deposunun bir özetidir , görünümler ve denetleyiciler kullanıcı arayüzünüzdür. Veri tabanları ve web gibi şeyler hakkında bilmek zorunda olmadıkları "sadece kod" olması gereken inşa ettiğiniz asıl uygulamanın çevresidir.
RemcoGerlich

2
"Model" kısmı, yüzlerce farklı yolla yorumlanır. Bana her zaman bir modelin bir temsil olduğu öğretildi. Model bir tren, gerçek bir trenin temsilidir, aynen gerçek olan gibi hareket eden küçük hareketli parçaları vardır. Benzer şekilde, uygulamanızdaki model, değiştirmek için yazılımınızı oluşturduğunuz sistemleri ve süreçleri temsil eder. Bu nedenle, modellerin davranışları vardır . Bu davranış "iş mantığınızı" içerir. Böylece, saf CRUD veri erişimini, kullanıcı arabirimini ve birlikte
çalışmayı yoksaydığınızda

1
@RemcoGerlich İş mantığı hakkında hiçbir şey söylemedim. Ben sadece MVC'nin yorumlarının çoğu model için başvuru durumunuzu temsil eden basit bir yapıdan başka bir şey olmadığı için, DB, API vb. Mantık ücretsiz. Veri tabanı ile iletişimde bulunma görevi denetleyiciye ya da denetleyici tarafından yönetilen başka bir nesneye düşmelidir.
CLW

12

M, V ve C'nin ne olduğu konusunda ortak (kasıtlı?) Bir yanlış anlaşılma var. Aldıkları roller hakkında değil , onlar ne .

MVC'nin orijinal masaüstü GUI tanımında modüllerdi . Tipik olarak bir uygulamanın birçoğu vardı, bazen üçüzler halinde çalışıyordu, bazen birkaç kontrolcünün karıştırıp eşleştirebileceği çeşitli görüşlere ve modellere sahipti.

Web çerçevelerinde OTOH, her birinin yalnızca bir tanesi olduğu katmanlar olarak görülmeye meyillidir ve çoğunlukla bazı sübstrasyonlu soyutlama seviyelerini kapsar: "model katmanı veri tabanını çıkarır", "görünüm katmanı sunum", "denetleyici" katman kullanıcı girdisini işler ".

Dolayısıyla, zaten veritabanınızla etkileşime adanmış bir modeliniz olduğunu ve şimdi kaynak API'nızla ilgilenmek için başka bir model oluşturmanız gerektiğini söyleyebilirim . Bunları mümkün olduğunca benzer yaparsanız, denetleyici ve görünüm kodunun çoğu her iki modelde de sorunsuz çalışabilir.


1
Anlaştık: Model (ler) in her zaman tüm problem alanı olması gerekiyordu. Karmaşık uygulamalarda her zaman kodun büyük olması gerekiyordu. Kullanıcı Arabirimini değiştirirseniz değişmeyecek olan tüm kodlardan oluşuyordu (örneğin, web sitesinden GUI'ye veya hatta komut satırı uygulamasına). Bir derleyici düşünün. Bir komut satırı kullanıcı arayüzünden bir GUI'ye veya hatta web kullanıcı arayüzüne geçtiğinizde, kodun yalnızca çok küçük bir kısmı değişebilir. Böyle bir uygulamanın tüm bağırsakları modellerdir.
Kevin Cathcart

1
Terimin orijinal Smalltalk kullanımında , arabirimdeki her UI denetiminin kendi modeli, görünümü ve denetleyicisi vardı.
RemcoGerlich

5

MVC'nin tartışılmasındaki zorlukların bir kısmı, farklı grupların farklı şeyler ifade etmek için kooperasyon yapmalarıdır. Bir Rails uygulamasında kullanılan MVC uygulaması, bir Swing uygulaması yazan bir kişi için neredeyse tanınmayacaktı. MVC'nin hala iyi tanımlanmış bir şey olduğu ölçüde, bir dizi yol gösterici ilkeden daha fazlasıdır (çekirdek uygulamayı görsel temsilinden ayırmak, ikisinin birlikte döşenmesini sağlamak için esnek mekanizmalar sağlamak). yolları.

Gerçekten de, farklı MVC türetilmiş tasarımlara farklı isimler verme eğilimi vardır ( bu konunun biraz tartışılması için bu makaleye bakınız ), hatta kesin isimlerden vazgeçme eğilimi vardır - örneğin, AngularJS kendini bir Model-View-Whatever olarak tanımlamaktadır. çerçeve.

Bu nedenle, hangi "MVC" versiyonunun üzerinde çalıştığınızı bilmeden cevap vermek zor. Bununla birlikte, bir API talebi tipik olarak çoğu uygulamada tamamen modelin içinde yer alacak olan çekirdek uygulamanın (farklı bir görsel sunum kullanmaya karar verirseniz değişmemesi gereken kısım) bir parçası olacaktır.


2

İşte , model şöyle açıklanmaktadır:

Bir model kontrol cihazına alınan ve görünümde görüntülenen verileri saklar. Verilerde herhangi bir değişiklik olduğunda, denetleyici tarafından güncellenir.

Denetleyicinin ya servisi arama mantığını içerdiğini ya da ayrı bir Servicenesneyi çağırdığını söyleyebilirim . Servis ayrıysa, daha kolay bir şekilde testler oluşturabilirsiniz, örneğin, bir şebeke üzerinden bir servisle bağlantı TestServicekurulamazsa , bazıları Serviceyerel olarak cevap verebilir .

Ayrıca Kontrolörün servisi aradığını öne süren bu cevaba da bakın.


2

Modeliniz hiçbir zaman gerçek bir kod içermemeli ve denetleyici tarafından manipüle edilen ve görünüm tarafından görüntülenen içeriği yönetmek için kullanılan bir mesaj veya yapı olarak görülmelidir.

Değişiklik isteyen herhangi bir API, veritabanı, hizmet vb. İle iletişim kurmaktan ve modelde gerekli güncellemeleri yönetmekten denetleyiciniz sorumlu olmalıdır.

MVC modelinin tüm gücü, mantığı (denetleyiciyi) görünüm ve durumdan (model) ayırmasıdır. Bunu yaparken, yalnızca kontrol cihazındaki kodun, görünüm ve modelde değişiklik yapmasına izin verilmediğinden yan etkiler yaratabileceğinin garantisi vardır.

Ayrıca, bir model çeşitli denetleyiciler ve görünümler arasında paylaşılabildiğinden, kodun daha iyi kullanılmasını sağlar.


4
Bence burada "model" derken, IMO'nun ayrı bir şey olduğu "viewmodel" e atıfta bulunuyorsunuz. Bir görünüm modeli denetleyiciden görünüme veri alır ve bu nedenle Görünümün bir uygulama detayı veya Görünüm ve Denetleyici arasındaki iletişimin bir yönü de ya da bunlara gerçekten uymayan bir şeydir (nasıl gördüğünüze bağlı olarak değişir). MVC'deki "Model" bir sistem modelini ifade eder - verilerini, yapısını ve davranışını içeren sistemin temsili. Model durum ve mantıktır; Denetleyici, mantık çalışmasına ve Görünüm manipüle edildiğinde durumun değişmesine neden olan şeydir.
anaximander

@anaximander Hayır MVC'nin oldukça katı bir yorumunda Modele atıfta bulunuyorum (bkz. Wikipedia, Microsoft MVC, Birinci Sınıf Tasarım desenleri, vb.) Bu durumlarda, Veri aktarımı için basit bir yapıdan başka bir şey değildir. etrafında ve bir görünüm modeli diye bir şey yoktur. Microsoft MVC uygulaması modele çeşitli özellikler eklese de, bu her şeyden daha kolaylık sağlamak içindir. Sonunda MVC şablonunun amacı, kod ayırma işleminin iyi uygulanmasını kolaylaştırmak ve yan etkileri sınırlandırmaktı.
CLW

1

Burada yoldan çıkmış olabilir, ancak WebApps hakkında hissediyorum ve birçok durumda [karmaşık] uzak API'lerle çalışmam böyle:

Bunu model yerine (yani veri azaltma işlevlerinin yığını) bir sınıf (yani bir veri azaltma yöntemleri kütüphanesi) yapardım. Görünüşe göre daha şeffaf, daha mantıksal / şema agnostik gibi gözüküyor ve onu kullanmak istediğiniz her seferde bir model / kontrolör çağırmadan herhangi bir yerde kullanmadan kullanabilirsiniz. Mantık hala ayrılmıştır, veri noktası hala esnektir ve uç noktayı dolaylı olarak yoklamak için istemciAJAX-> appJSON-> appLIB-> remoteAPI-> remoteJSON gibi istifleme gibi garip durumlarda birlikte çalışabilirlik için daha açık görünmektedir.

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.