มุมมองควรไม่ทำการตรวจสอบ


10

ฉันกำลังอ่าน " ในรูปแบบ MVC ควรจัดการกับการตรวจสอบหรือไม่ " เพราะฉันอยากรู้ว่าตรรกะการตรวจสอบควรอยู่ที่ใดในเว็บไซต์ MVC หนึ่งบรรทัดในคำตอบยอดนิยมจะเป็นดังนี้: "ตัวควบคุมควรจัดการกับการตรวจสอบความถูกต้องโมเดลควรจัดการกับการตรวจสอบความถูกต้อง"

ฉันชอบที่ แต่มันทำให้ฉันสงสัยว่าทำไมเราจะไม่ตรวจสอบข้อมูลในมุมมองด้วยเหตุผลหลายประการ:

  1. มุมมองมักมีการสนับสนุนการตรวจสอบที่มีประสิทธิภาพ (ไลบรารี JS, แท็ก HTML5)
  2. มุมมองสามารถตรวจสอบภายในเครื่องลด IO เครือข่าย
  3. UI ได้รับการออกแบบโดยคำนึงถึงประเภทข้อมูลเป็นหลัก (ปฏิทินสำหรับวันที่, ตัวหมุนสำหรับตัวเลข) ทำให้เป็นขั้นตอนเดียวจากการตรวจสอบความถูกต้อง

การยืนยันในที่มากกว่าหนึ่งแห่งนั้นตรงกันข้ามกับแนวคิดของ MVC ในการแยกความรับผิดชอบดังนั้น "การทำทั้งสองอย่าง" ดูเหมือนไม่เหมาะสม การตรวจสอบความถูกต้องของข้อมูลในคอนโทรลเลอร์เป็นวิธีการที่โดดเด่นอย่างแท้จริงหรือไม่?


ปัญหาที่นี่อาจเป็นหนึ่งในขั้วต่อที่ผิดพลาด: ไม่มีเหตุผลที่คุณไม่สามารถตรวจสอบความถูกต้องได้ในหลาย ๆ ที่และคิดว่าสถานการณ์เป็น "ไม่ว่าจะ - หรือ - ไม่ใช่ - ทั้งสอง" . ตัวอย่างเช่นการตรวจสอบความถูกต้องของฝั่งไคลเอ็นต์ในเว็บไซต์อาจมีประโยชน์จริง ๆ เนื่องจากผู้ใช้ได้รับการตอบกลับทันที แต่ก็ไม่น่าเชื่อถือดังนั้นจึงไม่สามารถทำการตรวจสอบได้เพียงอย่างเดียว
Miles Rout

คำตอบ:


10

ฉันไม่คิดว่าจะมีสถานที่เดียวที่คุณสามารถตรวจสอบความถูกต้องทั้งหมดได้ นี่เป็นเพราะเรามีกลยุทธ์การเขียนโปรแกรมการแข่งขันที่แตกต่างกันสองสามอันทำงานร่วมกันในเว็บไซต์ asp.net mvc มาตรฐาน

ประการแรกเรามีแนวคิดในการแยกลอจิกโดเมนออกเป็นโมเดลตรรกะ 'การกระทำ' เป็นตัวควบคุมและการแสดงผลเป็นมุมมอง นี่คือความคิดที่ว่าตรรกะทั้งหมดจะเกิดขึ้นบนเซิร์ฟเวอร์ด้วยเบราว์เซอร์เพียงแค่ให้มุมมอง

จากนั้นเราขยายมุมมองโดยใช้จาวาสคริปต์ฝั่งไคลเอ็นต์ นี่เป็นขั้นสูงในทุกวันนี้ที่แนวคิด 'เว็บไซต์หนึ่งหน้า' กับ Jquery / knockout / angular เป็นเรื่องธรรมดา

การปฏิบัตินี้สามารถเทียบเท่ากับการเขียนแอปพลิเคชันฝั่งไคลเอ็นต์ทั้งหมดซึ่งใช้รูปแบบ MVC หรือ MVVM เราปฏิเสธมุมมองไปยังวัตถุการถ่ายโอนข้อมูลและตัวควบคุมไปยังจุดสิ้นสุดบริการ การย้ายธุรกิจและตรรกะ UI ทั้งหมดไปยังไคลเอนต์

สิ่งนี้สามารถมอบประสบการณ์การใช้งานที่ดีขึ้น แต่คุณต้องเชื่อใจลูกค้าที่ไม่น่าไว้วางใจเป็นหลัก ดังนั้นคุณยังต้องดำเนินการตรวจสอบตรรกะบนเซิร์ฟเวอร์โดยไม่คำนึงว่าลูกค้าของคุณตรวจสอบคำขอได้ดีเพียงใด

นอกจากนี้เรามักจะมีข้อกำหนดการตรวจสอบซึ่งลูกค้าไม่สามารถทำได้ เช่น. 'รหัสใหม่ของฉันไม่ซ้ำกันหรือไม่'

แอปพลิเคชันใด ๆ ที่คุณสร้างขึ้นโดยมีเป้าหมายเพื่อมอบประสบการณ์ที่ดีที่สุด / ประสิทธิภาพจะต้องยืมสำหรับกระบวนทัศน์การเขียนโปรแกรมที่หลากหลายและประนีประนอมกับพวกเขาเพื่อให้บรรลุเป้าหมาย


4
+1 และเพื่อเน้น: อย่าเชื่อถือข้อมูลที่โพสต์โดยลูกค้า เคย
Machado

ฉันจะอ่านสิ่งนี้ได้อย่างไร: "การตรวจสอบความถูกต้องไม่ใช่แนวคิดที่แยกได้ - ทุกส่วนของแอปพลิเคชันของคุณต้องได้รับการตรวจสอบความถูกต้องกับบริบทอื่นในบริบทที่แตกต่างกัน" ทำให้รู้สึกถึงแม้ว่าทำงานได้มากขึ้น
WannabeCoder

ใช่ แต่ยัง: "คุณอาจมีสองแอป (หรือมากกว่า) ทุกรูปแบบที่แตกต่างกันดังต่อไปนี้"
Ewan

" den · i · grate : วิจารณ์อย่างไม่เป็นธรรมดูหมิ่น " ฉันไม่คิดว่าคุณใช้คำนั้นอย่างถูกต้อง คำตอบที่ดีเป็นอย่างอื่นแม้ว่า
kdbanman

ไม่นั่นคือสิ่งที่ฉันหมายถึง
Ewan

1

การยืนยันในที่มากกว่าหนึ่งแห่งนั้นตรงกันข้ามกับแนวคิดของ MVC ในการแยกความรับผิดชอบดังนั้น "การทำทั้งสองอย่าง" ดูเหมือนไม่เหมาะสม

มีหน้าที่ตรวจสอบความถูกต้องหลายอย่างเพื่อพิจารณาที่นี่หรือไม่ ตามที่คุณพูดไว้ใน # 3 ของคุณ:

UI ได้รับการออกแบบโดยคำนึงถึงประเภทข้อมูลเป็นหลัก (ปฏิทินสำหรับวันที่, ตัวหมุนสำหรับตัวเลข) ทำให้เป็นขั้นตอนเดียวจากการตรวจสอบความถูกต้อง

ดังนั้นอาจจะเป็น:

มุมมอง : ตรวจสอบประเภทอินพุตรูปแบบความต้องการ ... การตรวจสอบความถูกต้องอินพุตผู้ใช้ขั้นพื้นฐานที่ไม่เกี่ยวข้องกับตรรกะทางธุรกิจ จับทุกสิ่งที่นุ่มนี้ก่อนที่เราจะสร้างทราฟฟิกเครือข่ายโดยการร้องขอของเซิร์ฟเวอร์

รุ่น : ตรวจสอบความกังวลทางธุรกิจของข้อมูล นี่เป็นมูลค่าทางกฎหมายตามกฎเกณฑ์ทางธุรกิจหรือไม่? ใช่มันเป็นค่าตัวเลข (เรารับรองว่าในมุมมอง) แต่มันสมเหตุสมผลหรือไม่

แค่ความคิด


1

ฉันจะสมมติว่าคุณต้องการการตรวจสอบสำหรับความเพียร

ไม่เพียงแค่ดู แต่รุ่นไม่ควรตรวจสอบความถูกต้อง ในระหว่างวันของฉันใน IT ฉันรู้DDDเป็นหนึ่งในวิธีการเพื่อให้แน่ใจว่าคุณกำลังทำสิ่งต่าง ๆ อย่างถูกต้องเช่น ชั้นเรียนมีความรับผิดชอบในสิ่งที่ควรจะเป็นจริง

เมื่อติดตามการออกแบบที่ขับเคลื่อนด้วยโดเมนโมเดลของคุณจะมีตรรกะทางธุรกิจของคุณและนั่นก็คือ แต่พวกเขาไม่ได้รวมการตรวจสอบทำไมไม่?

สมมติว่าคุณใช้งานอยู่แล้วจนถึงData Mapperแทนที่จะใช้งานActive Recordเลเยอร์โดเมนของคุณต่อไป แต่ถึงกระนั้นคุณต้องการให้รุ่นได้รับการตรวจสอบความถูกต้องดังนั้นคุณจึงเพิ่มการตรวจสอบความถูกต้องในโมเดลของคุณ

interface Validation
{
    public function validate();
}

class ConcreteModel extends MyModel implements Validation
{
    public function validate() { // the validation logic goes here }
}

ตรรกะการตรวจสอบช่วยให้มั่นใจว่าคุณสามารถแทรกรูปแบบลงในฐานข้อมูล MySQL ของคุณได้อย่างถูกต้อง ... สองสามเดือนผ่านไปและคุณตัดสินใจว่าคุณต้องการจัดเก็บแบบจำลองของคุณในฐานข้อมูล noSQL เช่นกันฐานข้อมูลซึ่งต้องการกฎการตรวจสอบที่แตกต่างกัน

แต่คุณมีปัญหาคุณมีวิธีการตรวจสอบเพียงวิธีเดียว แต่ต้องตรวจสอบModelใน 2 วิธี

แบบจำลองควรทำในสิ่งที่พวกเขาต้องรับผิดชอบพวกเขาควรดูแลตรรกะทางธุรกิจของคุณและทำมันให้ดี การตรวจสอบจะเชื่อมโยงกับการติดตาไม่ตรรกะทางธุรกิจด้วยเหตุนี้การตรวจสอบไม่ได้อยู่ในรูปแบบ

คุณควรสร้างValidators แทนซึ่งจะใช้โมเดลเพื่อตรวจสอบความถูกต้องในคอนสตรัคเตอร์ของพวกเขาเป็นพารามิเตอร์ใช้Validationอินเตอร์เฟสและใช้Validators เหล่านี้เพื่อตรวจสอบวัตถุของคุณ

interface Validation
{
    public function validate();
}

class MySQLConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model here
    }
}

class RedisConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model with different set of rules here
    }
}

หากในอนาคตตัดสินใจว่าคุณต้องการเพิ่มวิธีการตรวจสอบอื่นสำหรับเลเยอร์การเก็บข้อมูลอื่น (เนื่องจากคุณตัดสินใจว่า Redis และ MySQL ไม่ใช่หนทางที่จะไปอีกต่อไป) คุณจะสร้างวิธีอื่นValidatorและใช้IoCคอนเทนเนอร์ของคุณเพื่อให้ได้อินสแตนซ์ที่เหมาะสม configบน


1

สำหรับนักพัฒนาหลายคนโมเดล Fat เทียบกับ Stupid Ugly Controllersเป็นวิธีที่ต้องการ

แนวคิดพื้นฐานในข้อความคือ

... โปรดจำไว้เสมอว่ารุ่นนี้ไม่ได้เป็นเพียงฐานข้อมูล แม้แต่ข้อมูลที่คุณได้รับจากบริการบนเว็บก็สามารถแสดงเป็นแบบจำลองได้! ใช่แล้วแม้แต่ฟีด Atom! กรอบที่สั่นสะเทือนจากการแนะนำให้รู้จักกับรุ่นแทบไม่เคยอธิบายเรื่องนี้ล่วงหน้าซึ่งมีเพียงความเข้าใจผิดที่รุนแรง

และ

ดูเฉพาะควรจะเกี่ยวข้องกับการสร้างและนำเสนอ UI เพื่อให้ผู้ใช้สามารถสื่อสารความตั้งใจที่จะรุ่น ตัวควบคุมคือผู้ควบคุมวงดนตรีที่แปลอินพุท UI เป็นการกระทำบน Model และส่งกลับเอาต์พุตจากมุมมองใดก็ตามที่ได้รับทราบถึงโมเดลที่มีการนำเสนอ ตัวควบคุมต้องกำหนดลักษณะการทำงานของแอปพลิเคชันเฉพาะในแง่ที่ว่าพวกเขาแมปอินพุตของผู้ใช้ไปยังการโทรในรูปแบบ แต่นอกเหนือจากบทบาทนั้นมันควรจะชัดเจนว่าตรรกะแอปพลิเคชันอื่น ๆ ทั้งหมดมีอยู่ในแบบจำลอง ตัวควบคุมเป็นสิ่งมีชีวิตต่ำต้อยที่มีรหัสน้อยที่สุดที่เพิ่งตั้งเวทีและปล่อยให้สิ่งต่าง ๆ ทำงานได้อย่างเป็นระเบียบ

มุมมองควรเกี่ยวข้องกับการสร้างและนำเสนอ UI เพื่อให้ผู้ใช้สามารถสื่อสารความตั้งใจต่อโมเดลเป็นส่วนสำคัญ แบบจำลองควรกำหนดข้อมูลที่เก็บไว้ดังนั้นมันจะต้องรับผิดชอบในการตรวจสอบความถูกต้องของข้อมูล

เมื่อทำการบันทึกของบุคคลแต่ละคนจะต้องมีหมายเลขประจำตัวที่ไม่ซ้ำกันที่กำหนดโดยประเทศ การตรวจสอบนี้ (โดยทั่วไป) จะทำโดยการUNIQUEตรวจสอบที่สำคัญโดยฐานข้อมูล แต่ละหมายเลข ID ที่ระบุควรเป็นไปตามขั้นตอนการควบคุมบางส่วน (ผลรวมของเลขคี่ควรเท่ากับผลรวมของเลขคู่เป็นต้น) การควบคุมประเภทนี้ควรทำโดยModel

ตัวควบคุมการเก็บรวบรวมข้อมูลจากModelและผ่านมันไปViewหรือย้อนกลับในการเก็บรวบรวมข้อมูลของผู้ใช้ผ่านและผ่านมันไปView Modelข้อ จำกัด ในการเข้าถึงข้อมูลและการตรวจสอบใด ๆ Controllerที่ไม่ควรทำโดย เป็นControllerผู้รวบรวมข้อมูลคุกกี้และเป็นข้อมูลModelที่ตรวจสอบว่าเป็นเซสชันที่ถูกต้องหรือผู้ใช้มีสิทธิ์เข้าถึงส่วนนี้ของแอปพลิเคชัน

Viewเป็นอินเทอร์เฟซผู้ใช้ที่รวบรวมข้อมูลจากผู้ใช้หรือนำเสนอข้อมูลไปยังผู้ใช้ การตรวจสอบอย่างง่ายสามารถทำได้โดยViewใช้ที่อยู่อีเมลที่ผู้ใช้ป้อนหรือไม่ (เช่นนี้สามารถทำได้ในมุมมอง) IMO

มุมมองเป็นฝั่งไคลเอ็นต์และคุณไม่ควรผลักดันอินพุตของผู้ใช้ Javascripts อาจล้มเหลวในการทำงานบนฝั่งไคลเอ็นต์ผู้ใช้สามารถใช้สคริปต์ที่เขียนด้วยลายมือเพื่อแก้ไขหรือปิดการใช้งานสคริปต์โดยใช้เบราว์เซอร์ คุณสามารถตั้งค่าสคริปต์การตรวจสอบฝั่งไคลเอ็นต์ แต่คุณไม่ควรไม่เคยผลักพวกเขาและทำการตรวจสอบจริงในModelชั้น


เพียงเพื่อเน้นมุมมองที่เกี่ยวข้องกับ UI เท่านั้นไม่ได้หมายความว่ามันไม่สามารถทำการตรวจสอบบางรูปแบบได้ - การให้ข้อเสนอแนะแก่ผู้ใช้ทันทีเมื่อพวกเขาทำผิดพลาดจริง ๆ แล้วเป็นส่วนสำคัญจริงๆของการเขียนสคริปต์ฝั่งไคลเอ็นต์ มีประโยชน์ในบริบทของ MVC ที่ใช้กับเว็บไซต์
Miles Rout

@MilesRout ในความเป็นจริงฉันหมายความว่าด้วยSimple checks can be done by the View like the user input e-mail address or not อาจจะไม่ชัดเจน แต่สิ่งที่คุณพูดนั้นเป็นจริงสำหรับฉันเช่นกันการตรวจสอบที่ง่ายและสะดวกสามารถทำได้โดยง่ายในมุมมอง
FallenAngel

ฉันไม่เห็นด้วยกับคุณ
Miles Rout

0

มุมมองควรดำเนินการตรวจสอบเพื่อ ff:

  1. ) การตรวจสอบส่วนหน้าสามารถลดทราฟฟิกข้อมูลในเซิร์ฟเวอร์ของคุณ
  2. ) มันจัดการข้อมูลที่ไม่ถูกต้องก่อนที่จะสามารถเดินทางไปยังเซิร์ฟเวอร์ของคุณ
  3. ) ถ้าคุณต้องการความปลอดภัยที่สูงขึ้นการรวมกันของส่วนหน้าและส่วนท้ายการตรวจสอบความถูกต้องจะดีกว่า
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.