it-swarm.asia

Model-View-Presenter uygulama düşünceleri

Bir kullanıcı arayüzü ve model arasında iyi bir ayrıştırmanın nasıl uygulanacağını iyi bir şekilde kavramaya çalışıyorum, ancak çizgileri tam olarak nereye böleceğimi bulmakta sorun yaşıyorum.

Model-View-Presenter'a bakıyordum, ancak tam olarak nasıl uygulanacağından emin değilim. Örneğin, Görünümümde birden çok iletişim kutusu var ..

  • Diyalogların her birinin örneklerini içeren bir View sınıfı olmalı mı? Bu durumda, iletişim kutuları Sunum Yapan ile nasıl etkileşime girmelidir? yani. bireysel bir iletişim kutusunun Presenter aracılığıyla Modelden veri istemesi gerekiyorsa, iletişim kutusu Presenter'a nasıl referans almalıdır? İnşaat sırasında kendisine verilen Görünüme atıf yoluyla?
  • Düşündüm belki manzara statik bir sınıf olmalı? Daha sonra GetView iletişim kutularını ve oradan Sunucuyu alın ...
  • Sunucuyu Görünüm ve Modelin sahipliğiyle (Sunum Yapan ve Sunum Yapan Modelin aksine) ve Sunum Yapanın Görünümdeki olaylar için geri arama kaydetmesini düşünüyordum, ancak bu çok fazla görünüyor daha fazla bağlı (veya dile bağlı, en azından.)

Deniyorum:

  1. bunu mümkün olduğunca ayırmalı yap
  2. ideal olarak Sunum Yapan/Modeli diğer dillerin Görünümleri ile eşleştirmeyi mümkün kılar (bir ton dil arası şey yapmadım, ancak bunun mümkün olduğunu biliyorum, özellikle daha void(void) en az bir C++ kütüphanesi olan bir C # uygulaması ...
  3. kodu temiz ve basit tut

Peki .. etkileşimlerin nasıl ele alınması gerektiği konusunda herhangi bir öneriniz var mı?

34
trycatch

Kaygan bir eğime hoş geldiniz. Bu noktaya kadar, tüm model-görünüm etkileşimlerinin sonsuz bir varyasyonu olduğunu fark ettiniz. MVC, MVP (Taligent, Dolphin, Pasif Görünüm), MVVM sadece birkaç isim.

Model Görünümü Sunucusu deseni, çoğu mimari desen gibi birçok çeşitliliğe ve deneye açıktır. Tüm varyasyonların ortak yanı, görüş ve model arasında “aracı” olarak sunum yapan kişinin rolüdür. En yaygın ikisi Pasif Görünüm ve Denetleyici Sunucu/Denetleyici - [ Fowler ]. Pasif Görünüm kullanıcı arayüzünü kullanıcı ve sunum yapan kişi arasında çok sığ bir arayüz olarak ele alır. Herhangi bir mantık varsa çok az içerir, bir sunucuya karşı sorumluluk kadar yetki verir. Sunucu/Denetleyiciyi Denetlemek birçok UI çerçevesine yerleştirilmiş veri bağından yararlanmaya çalışır. Kullanıcı arabirimi veri senkronizasyonunu yönetir ancak sunucu/denetleyici daha karmaşık mantık için devreye girer. Her iki durumda da model, görünüm ve sunum yapan kişi bir üçlü oluşturur

Bunu yapmanın birçok yolu var. Her iletişim kutusunu/formu farklı bir görünüm olarak ele alarak bunun ele alındığını görmek çok yaygındır. Çoğu zaman görünümler ve sunum yapan kişiler arasında 1: 1 bir ilişki vardır. Bu zor ve hızlı bir kural değil. Bir sunucunun birden fazla ilgili görüşü ele alması ya da tam tersi olması oldukça yaygındır. Her şey görüşün karmaşıklığına ve iş mantığının karmaşıklığına bağlıdır.

Görünümlerin ve sunum yapan kişilerin birbirlerine nasıl referans aldıklarına gelince, buna bazen kablolama denir. Üç seçeneğiniz var:

Görünüm, sunucuya referansta bulunuyor
Bir form veya diyalog bir görüş uygular. Formda, doğrudan işlev çağrılarını kullanarak bir sunucuya giden olay işleyicileri vardır:

MyForm.SomeEvent(Sender)
{
  Presenter.DoSomething(Sender.Data);
}

Sunum yapan kişinin görünüme referansı olmadığından, görünümün verileri bağımsız değişken olarak göndermesi gerekir. Sunum yapan kişi, görünümün dinlemesi gereken olaylar/geri arama işlevlerini kullanarak görünümle iletişim kurabilir.

Sunucunun görüntülemek için bir referansı var
Senaryoda görünüm, kullanıcıya görüntülediği verilerin özelliklerini gösterir. Sunucu olayları dinler ve görünümdeki özellikleri işler:

Presenter.SomeEvent(Sender)
{
  DomainObject.DoSomething(View.SomeProperty);
  View.SomeOtherProperty = DomainObject.SomeData;
}

Her ikisi de dairesel bir bağımlılık oluşturan birbirlerine referans veriyor
Bu senaryo ile çalışmak aslında diğerlerinden daha kolay. Görünüm, sunucudaki yöntemleri çağırarak olaylara yanıt verir. Sunucu, görünen özellikler aracılığıyla verileri görünümden okur/değiştirir.

View.SomeEvent(Sender)
{
  Presenter.DoSomething();
}

Presenter.DoSomething()
{
  View.SomeProperty = DomainObject.Calc(View.SomeProperty);
}

MVP modelleri ile dikkat edilmesi gereken başka hususlar da vardır. Yaratılış düzeni, kablolama yapılan nesne ömrü, MVP triadları arasındaki iletişim, ancak bu cevap zaten yeterince uzadı.

37
Kenneth Cochran

Herkesin dediği gibi düzinelerce fikir var ve bunların hiçbiri doğru ya da yanlış değil. Sayısız desene girmeden ve sadece MVP'ye odaklanmadan uygulama hakkında bazı öneriler.

Onları ayrı tutun. Görünüm, görünüm ve sunum yapan kişi arasındaki bağı oluşturan bir arabirim uygulamalıdır. Görünüm, bir sunum yapan kişi oluşturur ve kendini sunum yapan kişiye enjekte eder ve sunum yapan kişinin görünümle etkileşime girmesi için sunduğu yöntemleri ortaya koyar. Görüş, bu yöntemleri veya özellikleri istediği şekilde uygulamaktan sorumludur. Genellikle bir görünümünüz vardır: bir sunucu, ancak bazı durumlarda birçok görünümünüz olabilir: bir sunucu (web, wpf vb.). Buradaki anahtar, sunumcunun UI uygulamalarından hiçbir şey bilmemesi ve yalnızca arayüz aracılığıyla görünümle etkileşime girmesidir.

İşte bir örnek. İlk olarak, kullanıcıya bir mesaj görüntülemek için basit bir yöntemle bir görünüm sınıfımız var:

interface IView
{
  public void InformUser(string message);
}

Şimdi sunum yapan kişi. Sunucunun IView'i yapıcısına aldığını unutmayın.

class Presenter
{
  private IView _view;
  public Presenter(IView view)
  {
    _view = view;
  }
}

Şimdi asıl kullanıcı arayüzü. Bu bir pencere, iletişim kutusu, web sayfası vb. Olabilir. Görünümün yapıcısının kendisine enjekte ederek sunucu oluşturacağını unutmayın.

class View : IView
{
  private Presenter _presenter;

  public View()
  {
    _presenter = new Presenter(this);
  }

  public void InformUser(string message)
  {
    MessageBox.Show(message);
  }
}

Sunucu, görünümün sadece yaptığı yöntemi nasıl uyguladığına aldırmaz. Tüm sunum yapanların bildiği gibi, bir günlük dosyasına yazıyor olabilir ve kullanıcıya göstermiyor olabilir.

Her durumda, sunum yapan kişi arka uçtaki modelle bazı çalışmalar yapar ve bir noktada kullanıcıyı neler olduğu hakkında bilgilendirmek ister. Şimdi sunucuda bir yerde görünümler InformUser mesajını çağıran bir yöntem var.

class Presenter
{
  public void DoSomething()
  {
    _view.InformUser("Starting model processing...");
  }
}

Burada dekuplajınızı alırsınız. Sunucu sadece IView uygulamasına referans verir ve nasıl uygulandığını umursamaz.

Görünümde Presenter'a başvurduğunuzdan ve nesneler yapıcılar aracılığıyla ayarlandığından, bu da kötü bir uygulamadır. Daha sağlam bir çözümde, talep üzerine çalışma zamanında sizin için IView'in uygulanmasını çözecek ve böylece daha da ayrıştırılmış hale getirecek Windsor, Ninject, vb.

8
Bil Simser

Denetleyicinin/Sunumcunun eylemin gerçekten gerçekleştiği yer olduğunu hatırlamak önemlidir. Denetleyicideki kuplaj, gereklilik nedeniyle kaçınılmazdır.

Kontrolörün temel noktası, Görünümde bir değişiklik yaparsanız Modelin değişmesi ve tam tersi (Model değişirse Görünümün de değişmesi gerekmez) çünkü Kontrol Cihazı, Modeli Görünüme ve tekrar tekrar çeviren şeydir. Ancak, Model veya Görünüm değişiklikleri yapıldığında Kontrolör değişecektir, çünkü Kontrolör içinde Modelin nasıl göründüğünü Görüntülemek için Görünümde yapılan değişikliklerin Mod'a nasıl geri alınacağını etkili bir şekilde çevirmeniz gerekir.

Verebileceğim en iyi örnek, bir MVC uygulaması yazdığımda, sadece GUI görünümünde veriye sahip olmakla kalmayıp, Modelden çekilen verileri string içine iten bir rutin de yazabiliyorum hata ayıklayıcıda gösterilecek (ve uzantı olarak düz metin dosyasına). Model verilerini alıp Görünümü veya Modeli ve yalnızca Denetleyiciyi değiştirmeden serbestçe metne çevirebilirsem, o zaman doğru yoldayım.

Bununla birlikte, her şeyin çalışması için farklı bileşenler arasında referanslara sahip olmanız gerekecektir. Kontrol Ünitesinin Push to Push verileri hakkında bilgi sahibi olması gerekir, View'de bir kontrolün ne zaman yapıldığını bildirmek için Kontrol Ünitesini bilmesi gerekir (Kullanıcı "Kaydet" veya "Yeni ..." seçeneğini tıkladığında olduğu gibi). Denetleyicinin verileri çekmek için Model hakkında bilgi sahibi olması gerekir, ancak Modelin başka bir şey bilmemesi gerektiğini savunurum.

Caveat: Sizi gerçekten ister istemeseniz de MVC paradigmasına iten tamamen Mac, Objective-C, Cocoa arka planından geliyorum.

4
Philip Regan

Genel olarak, modelinizin bu modelle olan tüm etkileşimleri kapsamasını istersiniz. Örneğin, CRUD eylemleriniz (Oluşturma, Okuma, Güncelleme, Silme) modelin bir parçasıdır. Aynı şey özel hesaplamalar için de geçerlidir. Bunun için birkaç iyi neden var:

  • Bu kod için testinizi otomatikleştirmek daha kolay
  • Tüm bu önemli şeyleri tek bir yerde tutar

Oyun kumandanızda (MVC uygulaması) tek yaptığınız görünümünüzde kullanmanız gereken modelleri toplamak ve modeldeki uygun işlevleri çağırmaktır. Modelin durumunda herhangi bir değişiklik bu katmanda gerçekleşir.

Görünümünüz, hazırladığınız modelleri görüntüler. Temel olarak, görünüm sadece modeli okur ve çıktısını buna göre ayarlar.

Genel prensibi gerçek sınıflarla eşleme

Diyaloglarınızın görünüm olduğunu unutmayın. Zaten bir iletişim sınıfınız varsa, başka bir "Görünüm" sınıfı oluşturmak için hiçbir neden yoktur. Presenter katmanı esas olarak modeli Görünümdeki kontrollere bağlar. İş mantığı ve tüm önemli veriler modelde saklanır.

2
Berin Loritsch