Winforms çözümü için MVP'yi nasıl ayarlarım?


14

Geçmişte MVP ve MVC kullandım ve bence yürütme akışını çok daha iyi kontrol ettiği için MVP'yi tercih ediyorum.

Altyapımı (veri deposu / depo sınıfları) oluşturdum ve örnek verileri sabit kodlarken sorunsuz bir şekilde kullanıyorum, bu yüzden şimdi GUI'ye geçiyorum ve MVP'mi hazırlıyorum.

Bölüm A

  1. MVP görünümü giriş noktası olarak kullanarak gördüm, görünümleri oluşturucu yönteminde, sunum yapan, bu da olayları gerektiği gibi kablolama modeli oluşturur.

  2. Sunumu, bir görünüm, model ve sunum yapan kişinin oluşturulduğu giriş noktası olarak gördüm, bu sunum yapan kişiye olayları bağlamak için yapıcısında bir görünüm ve model nesnesi verilir.

  3. 2'de olduğu gibi, ancak model sunucuya geçmez. Bunun yerine model, yöntemlerin çağrıldığı ve yanıtların doğrudan döndürüldüğü statik bir sınıftır.

B bölümü

Görünümü ve modeli senkronize tutma açısından gördüm.

  1. Görünümdeki bir değer her değiştiğinde, yani TextChanged.Net / C # içindeki olay. Bu DataChangedEvent, her zaman senkronize kalması için modele aktarılan a'yı ateşler . Modelin değiştiği yerde, yani dinlediği bir arka plan olayı, görünüm aynı a DataChangedEvent. Bir kullanıcı değişiklik SaveEventyapmak istediğinde, kayıt yapmak için modele geçer. Bu durumda model, görünümün verilerini taklit eder ve eylemleri işler.

  2. Ancak # b1'e benzer şekilde görünüm her zaman modelle senkronize edilmez. Bunun yerine kullanıcı değişiklik yapmak istediğinde SaveEvent, işten çıkarılır ve sunum yapan kişi en son ayrıntıları alır ve bunları modele aktarır. bu durumda model, üzerinde işlem yapılması gerekene kadar görünüm verileri hakkında bilgi sahibi olmaz, bu durumda gerekli tüm ayrıntılar iletilir.

Bölüm C

İşletme nesnelerinin görünümde görüntülenmesi, yani ilkel veriler olmayan bir nesne (Sınıfım) (int, double)

  1. Görünüm, etki alanı / iş nesneleri olarak göstereceği tüm verileri için özellik alanlarına sahiptir. Bu gibi view.Animalsgösterir bir IEnumerable<IAnimal>özelliği, görünüm bir önizleme Düğümler içine bu işler halde. Sonra seçilen hayvan için mülkiyet SelectedAnimalolarak ortaya çıkardı IAnimal.

  2. Görünüm, etki alanı nesneleri hakkında bilgi sahibi değildir, yalnızca ilkel / çerçeve (.Net / Java) dahil nesne türleri için özellik sunar. Bu durumda, sunucu bir bağdaştırıcı nesnesini etki alanı nesnesini geçirir, bağdaştırıcı daha sonra belirli bir iş nesnesini görünümde görünen denetimlere çevirir. Bu durumda bağdaştırıcının görünümdeki gerçek denetimlere erişimi olmalıdır, yalnızca herhangi bir görünüm değil, daha sıkı bir şekilde bağlanır.

Bölüm D

Tek bir denetim oluşturmak için kullanılan birden çok görünüm. Yani, farklı türdeki nesneleri kaydetmek gibi basit bir modelle karmaşık bir görüşe sahipsiniz. Bir öğeye her tıklandığında uygun kontroller gösterilen bir menü sisteminiz olabilir.

  1. Görünümler arabirimi aracılığıyla açığa çıkarılan tüm denetimleri içeren büyük bir görünüm oluşturursunuz.

  2. Birkaç görüşünüz var. Menü için bir görünümünüz ve boş bir paneliniz var. Bu görünüm gerekli diğer görünümleri oluşturur, ancak bunları görüntülemez (visible = false), bu görünüm aynı zamanda içerdiği her görünüm (yani alt görünümler) için arabirimi uygular, böylece bir sunucuya gösterebilir. Boş panel diğer görünümlerle ( Controls.Add(myview)) ve ( (myview.visible = true) doldurulur . Bu "çocuk" görüşlerinde ortaya çıkan olaylar, olayı sunum yapan kişiye ileten ebeveyn görünümü tarafından ve alt öğelere geri olayların sağlanması için tam tersi şekilde gerçekleştirilir.

  3. İster ana ebeveyn olsun, ister küçük çocuk görüşleri olsun her görünüm kendi sunucu ve modeline bağlanır. Edebiyatla sadece bir görünüm kontrolünü mevcut bir forma bırakabilirsiniz ve işlevselliği hazır olacak, sadece sahne arkasındaki bir sunucuya kablolama gerekiyor.

Bölüm E

Her şeyin bir arayüzü varsa, şimdi yukarıdaki örneklerde MVP'nin nasıl yapıldığına dayalı olarak, çapraz uyumlu olmayabileceğinden bu yanıtı etkileyecektir.

  1. Her şeyin bir arayüzü vardır, Görünüm, Sunucu ve Model. Bunların her birinin açıkça somut bir uygulaması vardır. Sadece bir somut görüşünüz, modeliniz ve sunumcunuz olsa bile.

  2. Görünüm ve Modelin bir arayüzü vardır. Bu, görünümlerin ve modellerin farklı olmasına izin verir. Sunucu, görünüm ve model nesneleri oluşturur / verilir ve aralarında mesajlar iletmeye yarar.

  3. Yalnızca Görünüm'ün bir arayüzü vardır. Model statik yöntemlere sahiptir ve yaratılmamıştır, bu nedenle bir arayüze gerek yoktur. Farklı bir model istiyorsanız, sunucu farklı bir statik sınıf yöntemi kümesi çağırır. Statik olduğundan, Modelin sunum yapan kişiyle bağlantısı yoktur.

Kişisel düşünceler

Sunmuş olduğum tüm farklı varyasyonlardan (çoğu muhtemelen bir şekilde kullandım) daha fazlası olduğundan eminim. İş mantığını daha az veri çoğaltması ve daha az olay tetiklenmesi için sadece MVP, B2 dışında yeniden kullanılabilir olarak tutmayı tercih ediyorum. C1 başka bir sınıfa eklemediği için, bir görünüme (bir etki alanı nesnesinin nasıl görselleştirildiği) az miktarda birimsel test edilemez mantık koyduğundan emin olun, ancak bu kod incelenebilir veya uygulamada kolayca görüntülenebilir. Mantık karmaşık olsaydı, her durumda bir adaptör sınıfını kabul ederdim. D bölümü için, D1'in bir menü örneği için çok büyük olmayan bir görünüm oluşturduğunu hissediyorum. Daha önce D2 ve D3 kullandım. D2 ile ilgili sorun, sunum yapan kişiden olayları doğru alt görünüme yönlendirmek için çok sayıda kod yazmak zorunda kalmanız ve sürükle / bırak uyumlu olmaması, her yeni kontrol, tek sunucuyu desteklemek için daha fazla kablolamaya ihtiyaç duyar. D3 benim tercih ettiğim seçim olsa da, görünüm çok basit veya yeniden kullanılmaya gerek olmasa bile, görünümle ilgilenmek için sunum yapan kişiler ve modeller olarak daha fazla sınıf ekler. D2 ve D3'ün karışımının en iyi koşullara bağlı olduğunu düşünüyorum. E bölümüne gelince, bir arayüze sahip olan her şeyin aşırıya kaçmış olabileceğini düşünüyorum. Bunu zaten etki alanı / iş nesneleri için yapıyorum ve genellikle "tasarım" da böyle bir avantaj görmüyorum, ancak testlerde nesneleri alay etmeye yardımcı oluyor. Şahsen E2'yi daha önce üzerinde çalıştığım 2 projede kullanılmış olmasına rağmen klasik bir çözüm olarak görecektim. D2 ve D3'ün karışımının en iyi koşullara bağlı olduğunu düşünüyorum. E bölümüne gelince, bir arayüze sahip olan her şeyin aşırıya kaçmış olabileceğini düşünüyorum. Bunu zaten etki alanı / iş nesneleri için yapıyorum ve genellikle "tasarım" da böyle bir avantaj görmüyorum, ancak testlerde nesneleri alay etmeye yardımcı oluyor. Şahsen E2'yi daha önce üzerinde çalıştığım 2 projede kullanılmış olmasına rağmen klasik bir çözüm olarak görecektim. D2 ve D3'ün karışımının en iyi koşullara bağlı olduğunu düşünüyorum. E bölümüne gelince, bir arayüze sahip olan her şeyin aşırıya kaçmış olabileceğini düşünüyorum. Bunu zaten etki alanı / iş nesneleri için yapıyorum ve genellikle "tasarım" da böyle bir avantaj görmüyorum, ancak testlerde nesneleri alay etmeye yardımcı oluyor. Şahsen E2'yi daha önce üzerinde çalıştığım 2 projede kullanılmış olmasına rağmen klasik bir çözüm olarak görecektim.

Soru

MVP'yi doğru şekilde uyguluyor muyum? Bunun için doğru bir yol var mı?

Martin Fowler'in varyasyonları olan çalışmasını okudum ve MVC yapmaya ilk başladığımda konsepti anladım, ama başlangıçta giriş noktasının nerede olduğunu, her şeyin kendi işlevi var ama orijinali kontrol eden ve yaratan şeyi hatırlayamıyorum nesneleri kümesi.


2
Bu soruyu sormanın nedeni, neredeyse ilk denemede doğru bulmaya çalışıyorum. Aynı model için farklı varyasyonlar kullanarak 6 uygulama oluşturmak yerine standart bir MVP'yi tercih ederim.
JonWillis

Mükemmel ... Uzun süre sormak istedim
Kral

Yanıtlar:


4

Burada sunduğunuz şeylerin çoğu çok makul ve sağlam. Bazı seçimler, uygulamadaki ayrıntılara ve hangisinin "doğru" hissettiğine bağlı olacaktır. Çoğu zaman olduğu gibi, tek bir doğru cevap olmayacaktır. Bazı seçimler burada mantıklı olacaktır ve bu seçimler bir sonraki uygulama ve koşullar için tamamen yanlış olabilir. Uygulamanın bazı özelliklerini bilmeden, doğru yolda olduğunuzu ve sağlam, düşünceli kararlar verdiğinizi düşünüyorum.

Benim için, Sunumcunun neredeyse her zaman giriş noktası olması gerektiğini hissediyorum. Kullanıcı arabiriminin giriş noktası olması, kullanıcı arayüzüne çok fazla mantık getirir ve büyük kodlama değişiklikleri olmadan yeni bir kullanıcı arayüzünü değiştirme yeteneğini ortadan kaldırır. Ve bu gerçekten sunucunun işi.


Belki sormam gereken soru, MVP'yi sadece yanlış kullanmanın yollarından biridir. Farklı senaryolara uygun varyasyonlara katılıyorum, ancak genel kabul görmüş bir yaklaşım olması gerektiğini hissediyorum. MVP örnekleri bir etki alanı nesnesini düzenlemek ve değişiklikleri kaydetmek için basit örneklerdir ve neredeyse hepsi aynı ihtiyaçtır. Yine de aynı amaca sahip olan bu örneklerden yukarıdaki varyasyonlar üretilmiştir. Sunumda işlenmek üzere görünümde tetiklenen olayları kullanarak bir uygulamanın bir kısmını kodladım, ancak görünümün sunucuya bir referans tutmasını ve doğrudan çağrı yöntemlerini kullanmasını sağlayabilirdim.
JonWillis

Birimin test edilmemesini haklı çıkarmak için görüşü basitleştirecek tüm çabaları kabul ediyorum, o zaman sunum yapan kişi kontrol sahibi olmalıdır. Bununla ilgili tek endişem (kafamda düşünmek yanlış olabilir), winforms / usercontrols'un ana öğelerle bağlantılı olması ve yazmak için bir sunum yapan kişide ek mantığın gerekip gerekmediğini merak etmesidir.
JonWillis

MVP yanlış mı? Kitabımda görüşün sunum yapan kişiyi bilmesi olurdu. Çalışması anlamında "yanlış" olmayabilir ama sadece MVP olmaz, o noktada başka bir şeye dönüşür. Tasarım kalıplarındaki sorun, örneklerin her zaman mümkün olduğunca temiz ve basit olmasıdır. Onları ilk kez uygulamaya başladığınızda ve gerçek dünya sıçradığında ve 'hey gerçek uygulamalar bu cılız örnekten çok daha karmaşık' diyor. Büyümeniz burada başlar. Sizin ve uygulamanın koşulları için neyin işe yaradığını bulun.
Walter

tavsiye için teşekkürler. Üniversitede MVC öğrendiğimi hatırlıyorum. Harika görünüyordu ama boş bir tuvalle nereden başlayacağınızı ve gerçekten nasıl çalıştığını merak ediyorsunuz. MVP'nin yanlış olması açısından, demek istediğim, yanlış yapmanın üstünde yolladığım MVC'nin fikirlerinden / varyasyonlarından herhangi biri, yani sunum yapan kişinin nasıl çalıştığını bildiğinde. Ya da görünümün bir sunum yapan kişinin veya somut tipin bir arayüzüne referans olması gerekir. Hepsi aynı amaç için çalışabilen birçok farklı varyasyon.
JonWillis

1
@Jon - Varyasyonlarınız MVP ruhuna uygun. Arayüzler veya somut tiplerle çalışırken, uygulamanın koşullarına bağlı olacaktır. Uygulama oldukça küçükse, çok karmaşık değilse, belki de arayüz eklemek gerekli değildir. Uygulamanın kesinlikle X mimarisini uygulaması gerektiği açık olana kadar işleri olabildiğince basit tutmayı seviyorum. Daha fazla ayrıntı için bu cevaba bakınız: programmers.stackexchange.com/questions/34547/…
Walter

4

.NET 2.0 Winforms uygulamamızda değiştirilmiş bir MVP biçimi kullanıyoruz. Eksik olduğumuz iki parça, WPF ViewModel'in değiştirilmiş bir adaptörü ve veri bağlama ekliydi. Bizim özel modelimiz MVPVM'dir.

Tasarımcı dostu olmak için ilk bakışta kablolanan özel kullanıcı kontrolleri hariç, hemen hemen her durumda sunum yapan kişi olarak telgraf yapıyoruz. Bağımlılık enjeksiyonu, kod tarafından oluşturulan ViewModels, sunum yapan kişiler için BDD ve model için TDD / TED kullanıyoruz.

VM'ler, değiştirildiklerinde PropertyChanged'i yükselten devasa, düz, bir tomar özelliklerdir. Bunları kodla (ve ilişkili egzersiz birimi testleriyle) oluşturmak çok kolaydı. Bunları kullanıcı etkileşimli kontrollere okumak ve yazmak ve etkin durumları kontrol etmek için kullanırız. ViewModel, View ile birleştirilmiştir, çünkü her şeyin yakınında lanetlemek için veri bağlama kullanıyoruz.

Görünümde zaman zaman VM'nin yapamayacağı şeyleri başarmak için yöntemler bulunur. Bu genellikle öğelerin görünürlüğünü kontrol eder (WinForms bu konuda seçici olabilir) ve veriye bağlanmayı reddeden şeyleri kontrol eder. Görünüm her zaman "Login" veya "Restart" gibi olayları kullanıcı davranışları üzerinde işlem yapmak için uygun EventArgs ile gösterir. "View.ShowLoginBox" gibi bir kesmek kullanmamız gerekmedikçe, Görünüm genel tasarım gereksinimlerini karşıladığı sürece tamamen değiştirilebilir.

Bu paterni kesmek yaklaşık 6-8 ay sürdü. Çok fazla parçası var, ama çok esnek ve son derece güçlü. Bizim özel uygulama çok asenkron ve olay odaklı, bu sadece tasarım davranışının bir yan etkisi yerine, diğer gereksinimlerin bir yapay olabilir. Örneğin, VM'mizin devraldığı temel sınıfa iplik senkronizasyonu ekledim (bu, olayı yükseltmek için sadece bir OnPropertyChanged yöntemini ortaya çıkardı) - ve pof, şimdi çok iş parçacıklı sunumcu ve modellere sahip olabiliriz.


MVPVM'nizin ticari açıdan ilgi çekici olabileceğini biliyorum, ancak eğer uygunsa herhangi bir örnek kod verebilir misiniz? Yan notta, modelde neler yaptığını ve sunum yapan kişiye neler olduğunu çiziyorsunuz. Sunum o kadar basit gördüm ki olayları işliyorlar ve modeli çağırıyorlar.
JonWillis

Evet, bir örnek vereyim. Şirket içi bir eğitim aracı olarak kullandığım için işimize göre biraz uyarlanacak.
Bryan Boettcher

Teşekkür ederim, anladığımı görmek için haftasonuna bakacağım
JonWillis

@insta - bağlantı kesildi, bir yere yeniden yükleyebilir misiniz?
Yves Schelpe

1
Saçmalık Sadece bir hafta önce sildim. Rakamlar :(
Bryan Boettcher

2

.Net için değiştirilmiş ve sonra kendim tarafından geliştirilen bir PureMvc sürümünü kullanıyorum.

PureMvc'e Flex uygulamalarında kullanıyordum. Çıplak kemikli bir çerçeve türüdür, bu yüzden özelleştirmek istiyorsanız uyarlamak oldukça kolaydır.

Bununla birlikte şu özgürlükleri aldım:

  • Yansımayı kullanarak, form sınıfına girip aracılık ettiğim her kontrole (özel) referansı almak için görünüm aracısında özel özellikler elde etmeyi başardım.
  • Yansımayı kullanarak, kontrolleri arabulucumdaki jenerik olan olay imzalarına otomatik olarak bağlayabilirim, bu yüzden sadece gönderen parametresini açtım.
  • Normalde, PureMvc, türetilmiş arabulucuların bildirim ilgi alanlarını bir dizi dizeyi döndürecek bir işlevde tanımlamasını ister. İlgi alanım çoğunlukla statik olduğundan ve arabulucuların ilgi alanlarını görmenin daha kolay bir yoluna sahip olmak istediğimden, arabulucunun da çıkarlarını belirli bir imzası olan üye değişkenler kümesiyle belirleyebilmesi için bir değişiklik yaptım: _ _ _ <sınıf adı> _ <bildirim adı>. Bu şekilde bir işlevin içine bakmak yerine IDE üye ağacını kullanarak neler olduğunu görebiliyorum.

PureMvc'de, giriş noktası olarak bir Komut kullanabilirsiniz, tipik bir Başlat komutu Modeli olabildiğince ayarlayabilir, ardından MainForm'u oluşturabilir, bu form için ve bu formla birlikte arabulucu oluşturabilir ve kaydedebilir, ardından Application.Run formda.

Formun aracısı tüm alt-aracıların kurulmasından sorumlu olacaktır, bunların bir kısmı yansıma hileleri kullanılarak tekrar otomatik hale getirilebilir.

Eğer anlamını anlıyorsam, kullandığım sistem sürükle / bırak uyumludur. Gerçek form tüm VS'de oluşturulur, ancak benim deneyimim sadece statik olarak oluşturulmuş kontrollere sahip formlarla. Dinamik olarak oluşturulan menü öğeleri gibi şeyler, o menü veya alt menü için arabulucunun biraz ayarlanmasıyla mümkün görünmektedir. Kıllı olacağı yer, arabulucunun bağlanacak statik kök öğesi olmadığı ve dinamik 'örnek' arabulucular oluşturduğunuz zamandır.

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.