MVP deseninde Görünüm, UI içeriklerine dayalı bir Model nesnesi başlatmalı mı yoksa bu içerikleri Sunucu'ya parametre olarak mı aktarmalıdır?


9

Geliştirdiğim bir android uygulamasında MVP kalıbı kullanıyorum.

Temelde 4 elementim var:

  1. Yeni bir kullanıcının eklenebileceği AddUserView:
  2. AddUserPresenter
  3. UserInfo (pojo)
  4. UserInfoManager (iş mantığı ve depolama yöneticisi)

Sorum şu:

AddUserView içinde "Ekle" düğmesine bastığımda, metin görünümlerinin içeriğini almak, yeni bir UserInfo başlatmak ve Presenter'a iletmek gerekir. Yoksa AddUserView sadece textViews içeriğini almak ve onları aslında UserInfo örnek ve UserInfoManager geçirecek AddUserPresenter iletmek gerekir?

Yanıtlar:


8

Martin Fowler'in MVP açıklamasına göre ( http://martinfowler.com/eaaDev/uiArchs.html )

MVC'nin View kısmından Fowler şöyle diyor:

Potel'in ilk unsuru, görünümü Formlar ve Kontroller modelinin kontrollerine karşılık gelen widget'lar, widget'lar yapısı olarak ele almak ve herhangi bir görünüm / kontrolör ayrımını kaldırmaktır. MVP'nin görünümü bu widget'ların bir yapısıdır. Pencere öğelerinin kullanıcı etkileşimine nasıl tepki verdiğini açıklayan herhangi bir davranış içermez .

(Cesur vurgu benim)

Sonra sunum yapan kişinin:

Kullanıcıya karşı etkin tepki, ayrı bir sunucu nesnesinde yaşar. Kullanıcı hareketleri için temel işleyiciler hala widget'larda bulunur, ancak bu işleyiciler yalnızca kontrolü sunucuya iletir .

Ardından sunucu etkinliğe nasıl tepki vereceğine karar verir. Potel, bu etkileşimi öncelikle modeldeki komutlar ve seçimler sistemi tarafından gerçekleştirdiği eylemler açısından tartışır. Burada vurgulamak için yararlı bir şey, modeldeki tüm düzenlemeleri bir komutta paketleme yaklaşımıdır - bu, geri alma / yineleme davranışı sağlamak için iyi bir temel sağlar.

(Yine, cesur vurgu benim)

Bu nedenle, Fowler'in yönergelerine uygun olarak, Görünümünüz, düğme etkinliğine yanıt olarak herhangi bir davranıştan sorumlu olmamalıdır; bir örneği oluşturmayı içerir UserInfo. Bir nesne oluşturmaya karar verme sorumluluğu, UI etkinliğinin yönlendirildiği Presenter yöntemine aittir.

Ancak, Görünüm'ün düğme olay işleyicisinin de içeriğinizin iletilmesinden sorumlu olmaması gerektiği de iddia edilebilir textView, çünkü Görünüm yalnızca düğme olayını Sunum Yapan kişiye ve başka bir şeye yönlendirmemelidir .

MVP ile, görünümün, sunum yapan kişinin verileri doğrudan görünümden almak için kullanabileceği bir arabirimi uygulaması yaygındır (sunumu yapan kişi görünümün kendisinin hala agnostik olmasını sağlar). UserInfo basit bir POJO olduğundan, görünümün Presenter'ın bir arabirim aracılığıyla Görünüm'den alabileceği UserInfo için bir alıcı ortaya çıkarmak için geçerli olabilir .

// The view would implement IView
public interface IView {

    public UserInfo GetUserInfo();
}

// Presenter
public class AddUserPresenter {

    private IView addUserView;

    public void SetView(IView view) {
        addUserView = view
    }

    public void onSomethingClicked() {

        UserInfo userInfo = addUserView.GetUserInfo();
        // etc.
    }
}

Bu UserInfo, olay işleyiciyi kullanarak doğrudan görünüme geçmenin farkı nedir? Temel fark, bir nesnenin oluşturulmasına neden olan mantıktan sunum yapan kişinin sonuçta hala sorumlu olmasıdır UserInfo. yani olay, Sunucunun UserInfokarar vermesine izin vererek, oluşturulmadan önce Sunum Yapan kişiye ulaştı .

Sunum mantığına sahip olduğunuz UserInfove görünümdeki bir duruma göre oluşturulmasını istemediğiniz bir senaryo düşünün . Örneğin, kullanıcı görünümde bir onay kutusunu işaretlemediyse veya başarısız olan UserInfo'ya eklenecek bazı alanlara karşı bir doğrulama denetimi yaptıysanız - sunucunuz aramadan önce ek bir kontrol içerebilir GetUserInfo- ör.

    private boolean IsUsernameValid() {
        String username = addUserView.GetUsername();
        return (username != null && !username.isEmpty());
    }

    public void onSomethingClicked() {            

        if (IsUsernameValid()) {
            UserInfo userInfo = addUserView.GetUserInfo();
            // etc.
        }
    }

Bu mantık sunum yapan kişinin içinde kalır ve görünüme eklenmesi gerekmez. Görüş çağırmaktan sorumlu GetUserInfo()olsaydı, kullanımını çevreleyen herhangi bir mantıktan da sorumlu olurdu; MVP paterni bundan kaçınmaya çalışıyor.

Bu nedenle oluşturma yöntemi UserInfofiziksel olarak View sınıfında mevcut olsa da, hiçbir zaman View sınıfından değil, yalnızca Presenter'dan çağrılır.

Tabii ki, UserInfokullanıcı giriş widget'larının içeriğine karşı ek kontroller gerektiren uçların oluşturulması (örneğin, dize dönüştürme, doğrulama, vb.), O zaman doğrulama / dize dönüşümünün yapılabilmesi için bireysel alıcıları ortaya çıkarmak daha iyi olacaktır. Presenter içinde yer - ve sonra sunum yapan oluşturur UserInfo.

Genel olarak, Presenter / View arasındaki ayrılma konusundaki ana hedefiniz , görünümde asla mantık yazmanıza gerek kalmamasını sağlamaktır . Kendinizi ifherhangi bir nedenle bir ifade eklemeniz gerektiğini fark ederseniz if(bir widget özelliğinin durumu ile ilgili bir ifade olsa bile - boş bir metin kutusunu veya bir onay kutusunu işaretlemek için), o zaman sunum yapan kişiye aittir.


1
Büyük cevap @ BenCottrell! Ama başka bir tane var :) Sunum yöntemleri adlandırma iyi bir uygulama onSomethingClicked(), bu yüzden kullanıcı "bir şey" tıkladığında, View çağırır presenter.onSomethingClicked()? Ya da sunum yapan yöntemlerim, benim durumumda amaçlanan eylemler olarak adlandırılmalıdır addUser()?
Rômulo.Edu

1
@regmoraes İyi soru; ve bence örnek kodumda hafif bir koku var . PresenterUI mantığı yerine alanı mantığı için kurs sorumlu ait olduğunu ve özel olarak hazırlanmıştır Viewadlı bir yöntem bu yüzden olması gereken kavramlar, UI kavramlardır nedenle onSomethingClicked()çok yerinde olacaktır. Gez ile, yukarıdaki örneğimde seçtiğim adlandırma çok doğru kokmuyor :-).
Ben Cottrell

@BenCottrell Öncelikle harika yanıt için çok teşekkürler. Anladığım kadarıyla, bu GetUserInfoyöntemin belirttiğiniz gibi görünmesi geçerli (sunucudan tetiklenecek) Yöntemin ifiçindeki olası koşullar ne olacak GetUserInfo? Belki de UserInfo'nun bazı alanları kullanıcı tepkisi ile ayarlanır? Bir senaryo: Kullanıcı bir onay kutusu seçtikten sonra bazı yeni bileşenler (yeni bir EditText belki) kullanıcı tarafından görülebilir. Yani bu durumda, GetUserInfoeğer yöntem koşul olacaktır. Bu senaryoda GetUserInfohala geçerli mi?
blackkara

1
@Blackkara Görünüm modeliUserInfo olarak düşünün ("Modeli Görüntüle" olarak da bilinir) - Bu senaryoda , onay kutusunun durumunu ve metin kutusunun boş / boş durumunu eklerdim . POJO'nun tek gerçek amacı, Görünüm durumu hakkında bilgi bulmasına izin vermek olan bir sınıf olması açısından düşünmeye yardımcı olursa, yeniden adlandırmayı bile düşünebilirsiniz . booleanStringUserInfoUserInfoViewModelUserInfoPresenter
Ben Cottrell
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.