Menurut deskripsi Martin Fowler tentang MVP ( http://martinfowler.com/eaaDev/uiArchs.html )
Dari bagian Lihat MVC, Fowler mengatakan:
Elemen pertama Potel adalah memperlakukan tampilan sebagai struktur widget, widget yang sesuai dengan kontrol model Forms and Controls dan menghapus pemisahan tampilan / pengontrol. Pandangan MVP adalah struktur dari widget ini. Itu tidak mengandung perilaku apa pun yang menjelaskan bagaimana widget bereaksi terhadap interaksi pengguna .
(Penekanan tebal saya)
Kemudian dari presenter:
Reaksi aktif terhadap tindakan pengguna tinggal di objek presenter terpisah. Penangan dasar untuk gerakan pengguna masih ada di widget, tetapi penangan ini hanya memberikan kontrol kepada presenter .
Presenter kemudian memutuskan bagaimana bereaksi terhadap acara tersebut. Potel membahas interaksi ini terutama dalam hal tindakan pada model, yang dilakukan oleh sistem perintah dan pilihan. Hal yang berguna untuk disoroti di sini adalah pendekatan pengemasan semua suntingan ke model dalam suatu perintah - ini memberikan dasar yang baik untuk menyediakan perilaku undo / redo.
(Sekali lagi, penekanan milikku)
Jadi, sesuai dengan pedoman Fowler, Tampilan Anda tidak boleh bertanggung jawab atas perilaku apa pun sebagai respons terhadap peristiwa tombol; termasuk membuat instance dari UserInfo
. Tanggung jawab memutuskan untuk membuat objek adalah milik metode Presenter yang meneruskan acara UI.
Namun, orang juga dapat berargumen bahwa pengendali event tombol View juga tidak bertanggung jawab untuk meneruskan konten Anda textView
, karena View seharusnya hanya meneruskan peristiwa tombol ke Presenter dan tidak lebih.
Dengan MVP, pandangan umum untuk mengimplementasikan antarmuka yang presenter dapat gunakan untuk mengambil data langsung dari tampilan (sambil memastikan presenter masih agnostik dengan tampilan itu sendiri). Karena UserInfo adalah POJO sederhana, mungkin sah untuk tampilan untuk mengekspos pengambil untuk UserInfo yang Presenter dapat mengambil dari Tampilan melalui antarmuka.
// 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.
}
}
Apa bedanya dengan meneruskan UserInfo
langsung ke tampilan menggunakan pengendali acara? Perbedaan utama adalah bahwa presenter masih bertanggung jawab atas logika yang menyebabkan UserInfo
objek dibuat. yaitu acara mencapai Presenter sebelum penciptaan UserInfo
, yang memungkinkan Presenter untuk membuat keputusan.
Bayangkan sebuah skenario di mana Anda memiliki logika presenter di mana Anda tidak ingin itu UserInfo
dibuat berdasarkan pada beberapa keadaan dalam tampilan. Misalnya, jika pengguna belum mencentang kotak centang pada tampilan, atau Anda memiliki pemeriksaan validasi terhadap beberapa bidang yang akan ditambahkan ke dalam UserInfo yang gagal - presenter Anda mungkin berisi pemeriksaan tambahan sebelum memanggil GetUserInfo
- yaitu
private boolean IsUsernameValid() {
String username = addUserView.GetUsername();
return (username != null && !username.isEmpty());
}
public void onSomethingClicked() {
if (IsUsernameValid()) {
UserInfo userInfo = addUserView.GetUserInfo();
// etc.
}
}
Logika itu tetap ada di dalam presenter, dan tidak perlu ditambahkan ke dalam view. Jika pandangan bertanggung jawab untuk memanggil GetUserInfo()
maka itu juga akan bertanggung jawab untuk setiap logika seputar penggunaannya; itulah yang ingin dihindari oleh pola MVP.
Jadi, sementara metode yang menciptakan yang UserInfo
mungkin secara fisik ada di kelas View, itu tidak pernah dipanggil dari kelas View, hanya dari Presenter.
Tentu saja, jika pembuatan UserInfo
akhir memerlukan pemeriksaan tambahan terhadap konten widget input pengguna (mis. Konversi string, validasi, dll.), Maka akan lebih baik untuk mengekspos pengambil individu untuk hal-hal tersebut sehingga validasi / konversi string dapat dilakukan Tempatkan di dalam Presenter - dan kemudian presenter menciptakan UserInfo
.
Secara keseluruhan, tujuan utama Anda berkaitan dengan pemisahan antara Presenter / View adalah memastikan bahwa Anda tidak perlu menulis logika dalam tampilan. Jika Anda merasa perlu menambahkan if
pernyataan untuk alasan apa pun (bahkan jika itu adalah if
pernyataan tentang keadaan properti widget - memeriksa kotak teks kosong, atau boolean untuk kotak centang), maka itu milik di presenter.
onSomethingClicked()
, jadi ketika pengguna mengklik "sesuatu", Lihat panggilanpresenter.onSomethingClicked()
? Atau metode presenter saya harus dinamai sebagai tindakan yang dimaksud, dalam kasus sayaaddUser()
?