ตามคำอธิบายของ MVP ของ Martin Fowler ( http://martinfowler.com/eaaDev/uiArchs.html )
ในส่วนมุมมองของ MVC ฟาวเลอร์พูดว่า:
องค์ประกอบแรกของ Potel คือการปฏิบัติต่อมุมมองเป็นโครงสร้างของวิดเจ็ต, วิดเจ็ตที่สอดคล้องกับการควบคุมของแบบฟอร์มและการควบคุมและลบมุมมอง / ตัวควบคุมใด ๆ ออก มุมมองของ MVP เป็นโครงสร้างของวิดเจ็ตเหล่านี้ ไม่มีพฤติกรรมใด ๆ ที่อธิบายว่าวิดเจ็ตตอบสนองต่อการโต้ตอบของผู้ใช้อย่างไร
(เหมืองเน้นความหนา)
จากผู้นำเสนอ:
ปฏิกิริยาที่ใช้งานกับผู้ใช้จะทำหน้าที่อยู่ในวัตถุผู้นำเสนอแยกต่างหาก ตัวจัดการพื้นฐานสำหรับการท่าทางของผู้ใช้ยังคงอยู่ในเครื่องมือ แต่ขนย้ายวัสดุเหล่านี้เพียงผ่านการควบคุมไปยังพรีเซนเตอร์
ผู้นำเสนอจะตัดสินใจว่าจะตอบสนองต่อเหตุการณ์อย่างไร Potel กล่าวถึงการโต้ตอบนี้เป็นหลักในแง่ของการกระทำในรูปแบบซึ่งทำโดยระบบของคำสั่งและการเลือก สิ่งที่มีประโยชน์เพื่อเน้นที่นี่คือวิธีการบรรจุการแก้ไขทั้งหมดในรูปแบบในคำสั่ง - นี่เป็นรากฐานที่ดีสำหรับการแสดงพฤติกรรมการเลิกทำ / ทำซ้ำ
(อีกครั้งเหมืองเน้นตัวหนา)
ดังนั้นตามแนวทางของพรานล่าสัตว์มุมมองของคุณไม่ควรรับผิดชอบต่อพฤติกรรมใด ๆ ที่ตอบสนองต่อเหตุการณ์ปุ่ม UserInfo
ซึ่งรวมถึงการสร้างตัวอย่างของ ความรับผิดชอบในการตัดสินใจสร้างวัตถุเป็นของผู้นำเสนอวิธีการที่ส่งต่อเหตุการณ์ UI
อย่างไรก็ตามหนึ่งอาจโต้แย้งว่าตัวจัดการเหตุการณ์ปุ่มของมุมมองไม่ควรรับผิดชอบต่อการส่งเนื้อหาของคุณtextView
ด้วยเนื่องจากมุมมองควรส่งต่อเหตุการณ์ปุ่มไปยังผู้นำเสนอและไม่มีอะไรเพิ่มเติม
ด้วย MVP เป็นเรื่องปกติสำหรับมุมมองที่จะใช้อินเทอร์เฟซที่ผู้นำเสนอสามารถใช้เพื่อรับข้อมูลโดยตรงจากมุมมอง (ในขณะที่มั่นใจว่าผู้นำเสนอยังคงไม่เชื่อในมุมมองของตัวเอง) เนื่องจาก UserInfo เป็น POJO แบบง่ายจึงอาจใช้ได้สำหรับมุมมองที่จะแสดงให้เห็นgetterสำหรับ UserInfo ซึ่งผู้นำเสนอสามารถเลือกมุมมองจากอินเทอร์เฟซ
// 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.
}
}
สิ่งนี้แตกต่างจากการส่งผ่านUserInfo
โดยตรงไปยังมุมมองโดยใช้ตัวจัดการเหตุการณ์อย่างไร ข้อแตกต่างที่สำคัญคือผู้นำเสนอยังคงต้องรับผิดชอบต่อตรรกะในที่สุดซึ่งทำให้UserInfo
วัตถุถูกสร้างขึ้น เช่นเหตุการณ์ถึงผู้นำเสนอก่อนที่จะสร้างการUserInfo
อนุญาตให้ผู้นำเสนอในการตัดสินใจ
ลองนึกภาพสถานการณ์ที่คุณมีตรรกะของผู้นำเสนอที่คุณไม่ต้องการUserInfo
ให้สร้างขึ้นตามสถานะบางอย่างในมุมมอง ตัวอย่างเช่นหากผู้ใช้ไม่ได้ทำเครื่องหมายที่ช่องทำเครื่องหมายในมุมมองหรือคุณมีการตรวจสอบการตรวจสอบกับบางฟิลด์ที่จะเพิ่มลงใน UserInfo ซึ่งล้มเหลว - ผู้นำเสนอของคุณอาจมีการตรวจสอบเพิ่มเติมก่อนโทรGetUserInfo
- เช่น
private boolean IsUsernameValid() {
String username = addUserView.GetUsername();
return (username != null && !username.isEmpty());
}
public void onSomethingClicked() {
if (IsUsernameValid()) {
UserInfo userInfo = addUserView.GetUserInfo();
// etc.
}
}
ตรรกะนั้นยังคงอยู่ในผู้นำเสนอและไม่จำเป็นต้องเพิ่มลงในมุมมอง หากมุมมองรับผิดชอบต่อการโทรGetUserInfo()
ก็จะต้องรับผิดชอบต่อตรรกะใด ๆ ที่เกี่ยวข้องกับการใช้งาน รูปแบบ MVP พยายามหลีกเลี่ยงสิ่งใด
ดังนั้นในขณะที่วิธีการสร้างที่UserInfo
อาจมีอยู่จริงในคลาสมุมมองมันไม่เคยถูกเรียกจากคลาสมุมมองเฉพาะจากผู้นำเสนอ
แน่นอนหากการสร้างจุดUserInfo
สิ้นสุดต้องการการตรวจสอบเพิ่มเติมกับเนื้อหาของวิดเจ็ตการป้อนข้อมูลของผู้ใช้ (เช่นการแปลงสตริงการตรวจสอบความถูกต้อง ฯลฯ ) จะเป็นการดีกว่าที่จะแสดงตัวรับสัญญาณแต่ละตัวสำหรับสิ่งเหล่านั้น วางภายใน Presenter - UserInfo
พรีเซนเตอร์แล้วสร้างของคุณ
โดยรวมแล้วเป้าหมายหลักของคุณเกี่ยวกับการแยกระหว่างผู้นำเสนอ / มุมมองคือทำให้แน่ใจว่าคุณไม่จำเป็นต้องเขียนตรรกะในมุมมอง หากคุณเคยต้องการเพิ่มif
คำสั่งด้วยเหตุผลใดก็ตาม (แม้ว่าจะเป็นif
คำสั่งเกี่ยวกับสถานะของคุณสมบัติวิดเจ็ต - ตรวจสอบช่องว่างเปล่าหรือบูลีนสำหรับช่องทำเครื่องหมาย) แสดงว่าอยู่ในพรีเซนเตอร์
onSomethingClicked()
ดังนั้นเมื่อผู้ใช้คลิกที่ "บางอย่าง" การเรียกดูpresenter.onSomethingClicked()
? หรือวิธีการเสนอชื่อของฉันควรตั้งชื่อเป็นการกระทำที่ตั้งใจไว้ในกรณีของฉันaddUser()
?