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 UserInfo
karar vermesine izin vererek, oluşturulmadan önce Sunum Yapan kişiye ulaştı .
Sunum mantığına sahip olduğunuz UserInfo
ve 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 UserInfo
fiziksel 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, UserInfo
kullanı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 if
herhangi 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.
onSomethingClicked()
, bu yüzden kullanıcı "bir şey" tıkladığında, View çağırırpresenter.onSomethingClicked()
? Ya da sunum yapan yöntemlerim, benim durumumda amaçlanan eylemler olarak adlandırılmalıdıraddUser()
?