MVC desenini bir C # WinForms uygulamasına nasıl uygulayabilirim?


11

O zamandan beri GUI'leri tasarlamak için MVC desenini kullanan bir C ++ geliştiricisiyim.

Son zamanlarda C # 'a geri dönmek istedim ve bir Windows Forms uygulaması kurdum, ancak şimdi MVC uyumlu bir yapıya nasıl iteceğim konusunda biraz kayboldum.

Şu anda yapmaya çalıştığım bir görünüm olarak WinForms için verilen sınıf "beyan" ve arka planda Model ve Denetleyici için bir sınıf eklemek için. Ancak, bir düğme tıklaması gibi etkinliklerle nasıl etkileşime gireceğinden emin değilim. Genellikle bu olayları denetleyiciye yönlendirir ve işim bittiğinde Görünüm üzerinde bir eylem gerçekleştiririm.

Bu, bu takımyıldızda oldukça tatmin edici hissetmemektedir. Örneğin, bir "Çıkış" düğmesi uygulamak istersem, olayı Görünüm'den Denetleyiciye yeniden yönlendirmem ve ayrıca Görünümümde daha sonra Denetleyiciden çağrılabilecek ekstra bir genel yöntem uygulamam gerekir. ilk örnekte Görünümden Close () yöntemini çağırabilir.

benim için herhangi bir öneriniz var mı? C # Windows Forms benim anlayış henüz bir MVC uygulamasını denemek için yeterince iyi değil mi? Form sınıfına yanlış bir rol mü veriyorum? MVC bu kullanım durumu için uygun olmayan bir mimari midir?


1
OT sorusu. Ama neden WInforms? WPF'nin Winforms yerine geçmesi ve MVC'yi (teknik olarak MVVM) desteklemesi amaçlanmıştır. Her ne kadar WPF öğrenme eğrisinin dik olabileceğini söyleyeceğim. (ancak bunu kötü yaparsanız, WPF kodunu Winform'lara benzetebilirsiniz)
Peter M

1
@PeterM: çünkü 10 yıl sonra bile WPF berbat ve hala yavaş.
whatsisname

3
@ Whatsisname'nin yorumunu açıklamak için WPF daha büyük uygulamalara yöneliktir. Winforms ile daha küçük uygulamalar daha iyi sunulabilir çünkü Winforms tartışmasız daha basittir. Ancak, bu argümanı yapmak istiyorsanız, Winforms uygulamanızın zaten MVP'ye ihtiyaç duymadığı yerlerde yeterince küçük olduğu argümanını da yapabilirsiniz. MVVM, WPF'ye pişirilir. WPF'nin vektör tabanlı grafikleri vardır, bu nedenle Winforms ile aynı boyutlandırma sorunlarına maruz kalmaz. WPF çok oluşturulabilir (kontrolleri diğer kontrollerin içine kolayca koyabilirsiniz) ve katil veri bağlaması var. Ne gibi değil?
Robert Harvey

3
@ whatsisname WPF emebilir, ancak bir oyuncak programının üstündeki her şey için Winforms'tan çok daha az berbat
Peter M

2
Şirket içi masaüstü programları için bunu söyleyebilirim. Ancak birçok şirket, yalnızca kurulum gerektirmediği için iş operasyonları için tarayıcı tabanlı uygulamaları tercih ediyor.
Robert Harvey

Yanıtlar:


3

Tesadüfen, MVC'den sonra oluşturulan bir WinForms projesi üzerinde çalışıyorum. Buna mükemmel bir cevap demem, ama genel tasarımımı açıklayacağım ve umarım bu sizin kendi başınıza gelmenize yardımcı olabilir.

Bu projeye başlamadan önce yaptığım okumaya dayanarak, bunu uygulamanın "doğru" yolu yok gibi görünüyor. Basit OOP ve MVC tasarım ilkelerini izledim ve geri kalanı bir iş akışı geliştirdiğim için deneme yanılma yöntemiydi.

MVC bu kullanım durumu için uygun olmayan bir mimari midir?

Hayır ..? Sorunuzda buna doğrudan bir cevap vermek için yeterli bağlam yok. İlk etapta neden MVC kullanıyorsunuz? Projenizin işlevsel olmayan gereksinimleri nelerdir? Projeniz çok kullanıcı arayüzü ağır mı olacak? Güvenlik konusuna daha fazla önem veriyor musunuz ve katmanlı bir mimari mi tercih ediyorsunuz? Projenizin ana bileşenleri nelerdir? Belki de her bileşen farklı bir tasarım modeline ihtiyaç duyar. Neden bu tasarım desenini kullanmak istediğinizi öğrenin ve kendi sorunuza cevap verebilirsiniz;)

MVC kullanma nedenim: benim görüşüme göre anlaşılması oldukça basit bir tasarım deseni ve tasarımım büyük ölçüde kullanıcı etkileşimine dayanıyor. MVC'nin geliştiricilerin endişeleri ayırmasına izin vermesi de başvurum için yeterli. Bu, kodumu çok daha sürdürülebilir ve test edilebilir hale getirir .

Sanırım daha çok hibrit bir tasarım kullanıyorum. Genellikle, yazılım mühendisliğinde sunulan ideal konsept aslında pratikte geçerli değildir. Tasarımı, projenizin gereksinimlerine uyacak şekilde değiştirebilirsiniz. Doğru ya da yanlış olanı yakalamaya gerek yok. Genel uygulamalar vardır, ancak kendinizi ayağa vurmadığınız sürece kurallar her zaman bükülebilir veya kırılabilir.

Uygulamam, hangi bileşenlere ihtiyacım olacağına dair bana bir fikir veren üst düzey bir tasarımla başladı. Bu şekilde başlamak ve mimaride aşağı inmek en iyisidir. İşte proje için paket diyagramı (StarUML'de yaratılmıştır): resim açıklamasını buraya girin

Sunum katmanı dışındaki her katmanın Mesajlaşma Sistemine bağlı olduğuna dikkat edin. Bu, bu katmanların alt katmanlarının ve alt sistemlerinin birbirleriyle iletişim kurmak için kullandığı yaygın bir "dildir". Benim durumumda, yapılabilecek işlemlere dayanan basit bir numaralandırma idi. Bu da beni bir sonraki noktaya getiriyor ...

İşlemleri veya komutları uygulamanızın temeli olarak düşünün. Başvurunuzun ne yapmasını istiyorsunuz? En temel operasyonlara ayırın. Örneğin: CreateProject, WriteNotes, SaveProject, LoadProject vb. GUI (veya Form sınıfları) bir olay meydana getirecektir (düğme basma gibi). Her işlemin kendisiyle ilişkili bir denetleyici yöntemi vardır. Bu durumda Çıkış gibi bir şey çok basittir. Uygulama Form sınıfından kapatılabilir. Ama önce bazı uygulama verilerini bir dosyada saklamak istediğimi varsayalım? Düğmeye basma yöntemimdeki ilgili denetleyici sınıfından "Kaydet" yöntemini çağıracağım.

Oradan, kontrolör Servis sınıflarından doğru işlem setini çağıracaktır. Uygulamamdaki hizmet sınıfları, etki alanı katmanına bir arabirim görevi görür. Denetleyici yöntem çağrısından (ve böylece GUI'den) alınan girdiyi doğrular ve veri modelini değiştirir.

Doğrulama ve ilgili nesne değiştirme işlemi tamamlandığında, hizmet yöntemi denetleyiciye bir ileti kodu döndürür. Örneğin MessageCodes.SaveSuccess,. Hem denetleyici hem de hizmet sınıfları, etki alanı nesnelerine ve / veya birlikte gruplandırılabilen genel işlem kümesine dayanıyordu.

Örneğin: FileMenuController(işlemleri: NewProject, SaveProject, LoadProject) -> ProjectServices(CreateProject, PersistProjectToFile, LoadProjectFromFile). ProjectVeri modelinizde bir etki alanı sınıfı nerede olur? Benim durumumda Controller ve Service sınıfları statik yöntemlerle oluşturulamayan sınıflardı.

Ardından, kontrolör işlemi un / başarılı olarak tamamladığını tanır. Şimdi, denetleyicinin sunum katmanıyla etkileşim kurmak için kullandığı kendi mesajlaşma sistemi vardır, bu nedenle Hizmet ve Sunum katmanları arasında çift bağımlılık vardır. Bu durumda ViewState, ViewModelspakette çağrılan bir sınıf her zaman denetleyici tarafından GUI'ye döndürülür. Bu durum aşağıdaki gibi bilgileri içerir: " Uygulamayı geçerli hale getirmeye çalıştığınız durum mu? ", " Gerçekleştirmeye çalıştığınız işlem ve neden başarılı veya başarısız olduğu (hata mesajları) " ve bir ViewModelsınıf hakkında okunabilir bir mesaj .

ViewModelSınıf GUI görünümünü güncelleştirmek için kullanacağı alanı katmandan ilgili verileri içerir. Bu görünüm modelleri etki alanı sınıflarına benziyor ama benim durumumda çok sıska nesneler kullandım. Temelde hemen hemen hiç davranışları yoktur, sadece uygulamanın alt düzey durumu hakkında bilgi aktarırlar. Başka bir deyişle, etki alanı sınıflarımı sunum katmanına ASLA vermeyeceğim. Bu nedenle Controllersve Servicespaketleri de hizmet katmanını iki kısma ayırır. Denetleyiciler hiçbir zaman etki alanı sınıflarını işlemez veya durumlarını doğrulamaz. GUI ile ilgili verileri, hizmetlerin kullanabileceği alanla ilgili verilere ve tersine çeviren bir sınır görevi görürler. Servis mantığının kontrolöre dahil edilmesi çok şişmanlığa neden olur bakımı daha zor olan kontrol cihazları.

Umarım bu size bir başlangıç ​​noktası verir.

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.