ใน Ruby on Rails Development (หรือ MVC โดยทั่วไป) ฉันควรทำตามกฎอย่างรวดเร็วว่าจะวางตรรกะไว้ที่ใด
กรุณาตอบด้วยการยืนยัน - ด้วยอย่าใส่สิ่งนี้ไว้ที่นี่แทนที่จะทำอย่างนั้น
ใน Ruby on Rails Development (หรือ MVC โดยทั่วไป) ฉันควรทำตามกฎอย่างรวดเร็วว่าจะวางตรรกะไว้ที่ใด
กรุณาตอบด้วยการยืนยัน - ด้วยอย่าใส่สิ่งนี้ไว้ที่นี่แทนที่จะทำอย่างนั้น
คำตอบ:
MVC
ตัวควบคุม : ใส่รหัสที่นี่ซึ่งเกี่ยวข้องกับการทำงานตามที่ผู้ใช้ต้องการและตัดสินใจว่าจะให้พวกเขาทำงานอย่างไรไม่ว่าพวกเขาจะเข้าสู่ระบบไม่ว่าพวกเขาควรจะเห็นข้อมูลบางอย่าง ฯลฯ ในท้ายที่สุดตัวควบคุมจะดูคำขอ และทำงานหาข้อมูล (รุ่น) ที่จะแสดงและมุมมองที่จะแสดงผล หากคุณมีข้อสงสัยเกี่ยวกับว่ารหัสควรไปในตัวควบคุมแล้วมันอาจไม่ควร ให้ควบคุมของคุณผอม
มุมมอง : มุมมองควรมีรหัสขั้นต่ำเท่านั้นเพื่อแสดงข้อมูลของคุณ (รุ่น) ซึ่งไม่ควรทำการประมวลผลหรือคำนวณจำนวนมาก แต่ควรแสดงข้อมูลที่ถูกคำนวณ (หรือสรุป) โดยตัวแบบหรือสร้างจากคอนโทรลเลอร์ ถ้ามุมมองของคุณจำเป็นต้องทำการประมวลผลที่ไม่สามารถทำได้โดยตัวแบบหรือตัวควบคุมให้ใส่รหัสในตัวช่วย โค้ด Ruby จำนวนมากในมุมมองทำให้มาร์กอัปอ่านยาก
รุ่น : โมเดลของคุณควรเป็นที่ที่รหัสทั้งหมดของคุณเกี่ยวข้องกับข้อมูลของคุณ (เอนทิตีที่สร้างเว็บไซต์ของคุณเช่นผู้ใช้โพสต์บัญชีเพื่อน ฯลฯ ) อาศัยอยู่ หากรหัสต้องการบันทึกอัปเดตหรือสรุปข้อมูลที่เกี่ยวข้องกับเอนทิตีของคุณให้ใส่ที่นี่ มันจะสามารถใช้งานได้อีกครั้งในมุมมองและตัวควบคุมของคุณ
วิธีเพิ่มคำตอบของ pauliephonic:
ตัวช่วย : ฟังก์ชั่นเพื่อทำให้การสร้างมุมมองง่ายขึ้น ตัวอย่างเช่นหากคุณวนซ้ำรายการวิดเจ็ตเพื่อแสดงราคาของพวกเขาให้วางไว้ในตัวช่วย (พร้อมด้วยบางส่วนสำหรับการแสดงผลจริง) หรือถ้าคุณมีชิ้นส่วนของ RJS ที่คุณไม่ต้องการให้มุมมองวุ่นวายให้ใส่มันเข้าไปในตัวช่วย
รูปแบบ MVC เกี่ยวข้องกับ UI จริง ๆ เท่านั้น คุณไม่ควรใส่ตรรกะทางธุรกิจที่ซับซ้อนลงในคอนโทรลเลอร์เพราะมันจะควบคุมมุมมอง แต่ไม่ใช่ตรรกะ ผู้ควบคุมควรคำนึงถึงตัวเองด้วยการเลือกมุมมองที่เหมาะสมและมอบหมายสิ่งที่ซับซ้อนมากขึ้นให้กับรูปแบบโดเมน (Model) หรือชั้นธุรกิจ
การออกแบบโดเมนขับเคลื่อนมีแนวคิดของบริการซึ่งเป็นสถานที่ที่คุณติดตรรกะซึ่งจำเป็นต้องจัดวางวัตถุประเภทต่าง ๆ จำนวนมากซึ่งโดยทั่วไปหมายถึงตรรกะที่ไม่ได้อยู่ในชั้นเรียนแบบตามธรรมชาติ
โดยทั่วไปฉันคิดว่า Service layer เป็น API ของแอปพลิเคชันของฉัน เลเยอร์บริการของฉันมักจะจับคู่กับความต้องการของแอปพลิเคชันที่ฉันสร้างอย่างใกล้ชิดดังนั้นเลเยอร์บริการทำหน้าที่ทำให้การโต้ตอบที่ซับซ้อนมากขึ้นง่ายขึ้นซึ่งพบได้ในระดับล่างของแอปของฉันนั่นคือคุณสามารถบรรลุเป้าหมายเดียวกันได้ แต่คุณต้องดึงคันโยกให้มากขึ้นเพื่อให้ทำงานได้
โปรดทราบว่าฉันไม่ได้พูดถึง Rails ที่นี่ฉันกำลังพูดถึงรูปแบบสถาปัตยกรรมทั่วไปที่จัดการปัญหาเฉพาะของคุณ
คำอธิบายที่สมบูรณ์แบบอยู่ที่นี่แล้วประโยคที่เรียบง่ายหนึ่งประโยคเป็นบทสรุปและจดจำได้ง่าย:
เราต้องการรุ่น SMART, THIN Controllers และ DUMB Views
ใส่สิ่งที่เกี่ยวข้องกับการอนุญาต / ควบคุมการเข้าถึงในคอนโทรลเลอร์
แบบจำลองทั้งหมดเกี่ยวกับข้อมูลของคุณ การตรวจสอบความสัมพันธ์, CRUD, ตรรกะทางธุรกิจ
จำนวนการดูเป็นเรื่องเกี่ยวกับการแสดงข้อมูลของคุณ แสดงและรับอินพุตเท่านั้น
ตัวควบคุมกำลังเกี่ยวกับการควบคุมข้อมูลที่จะไปจากแบบจำลองของคุณไปยังมุมมองของคุณ (และมุมมองใด) และจากมุมมองของคุณไปยังแบบจำลองของคุณ ตัวควบคุมสามารถอยู่ได้โดยไม่มีรุ่น
ฉันชอบคิดว่าตัวควบคุมเป็นพนักงานรักษาความปลอดภัย / พนักงานต้อนรับที่นำลูกค้าของคุณ (ขอ) ไปที่เคาน์เตอร์ที่เหมาะสมที่คุณถามคำถามพนักงานขาย (ดู) พนักงานฝากเงิน (ดู) จากนั้นไปและรับคำตอบจากผู้จัดการ (รุ่น) ที่คุณไม่เคยเห็น คุณร้องขอจากนั้นกลับไปที่พนักงานรักษาความปลอดภัย / พนักงานต้อนรับ (ตัวควบคุม) และรอจนกว่าคุณจะถูกนำไปบอกพนักงานคนอื่น (ดู) ที่บอกคำตอบกับผู้จัดการ (รุ่น) บอกพวกเขาในการตอบคำถามของคนอื่น (มุมมอง) .
ในทำนองเดียวกันหากคุณต้องการบอกพนักงาน (ดู) บางสิ่งบางอย่างส่วนใหญ่แล้วสิ่งเดียวกันจะเกิดขึ้นยกเว้นพนักงานที่สองจะบอกคุณว่าผู้จัดการยอมรับข้อมูลของคุณหรือไม่ อาจเป็นไปได้ว่าเจ้าหน้าที่รักษาความปลอดภัย / พนักงานต้อนรับ (ตัวควบคุม) อาจบอกให้คุณเดินขึ้นเขาเนื่องจากคุณไม่ได้รับอนุญาตให้แจ้งข้อมูลดังกล่าวกับผู้จัดการ
ดังนั้นเพื่อขยายคำอุปมาในโลกที่ตายตัวและไม่สมจริงของฉันผู้บอกเล่า (มุมมอง) นั้นสวย แต่ไร้สมองและมักจะเชื่อสิ่งที่คุณบอกพวกเขาเจ้าหน้าที่รักษาความปลอดภัย / พนักงานต้อนรับนั้นสุภาพเล็กน้อย แต่ไม่ค่อยมีความรู้มากนัก ไม่ควรไปและผู้จัดการน่าเกลียดจริง ๆ และมีความหมาย แต่รู้ทุกอย่างและสามารถบอกได้ว่าอะไรจริงและอะไร
สิ่งหนึ่งที่ช่วยแยกอย่างถูกต้องคือการหลีกเลี่ยง "รูปแบบการส่งผ่านตัวแปรในท้องถิ่นจากตัวควบคุมเพื่อดู" แทนสิ่งนี้:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
def show
@foo = Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...
ลองย้ายไปที่ทะเยอทะยานที่มีอยู่ในวิธีการช่วยเหลือ:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
helper_method :foo
def show
end
protected
def foo
@foo ||= Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...
สิ่งนี้ทำให้ง่ายต่อการปรับเปลี่ยนสิ่งที่ได้รับใน "@foo" และวิธีการใช้งาน มันเพิ่มการแยกระหว่างตัวควบคุมและมุมมองโดยไม่ทำให้ซับซ้อนมากขึ้น
foo
และจาก@foo
นั้นเหมือนกัน - ทั้งคู่ถูกกำหนดขอบเขตไว้ที่คู่ <ControllerClass, request> นอกจากนี้โดยใช้เวอร์ชัน getter ฉันสามารถเปลี่ยนวิธีการFoo
ค้นหา / จัดเก็บ / แคชของวัตถุโดยไม่เปลี่ยนวิธีการที่มุมมองเข้าถึง
ทีนี้มันขึ้นอยู่กับว่าตรรกะนั้นเกี่ยวข้องกับอะไร ...
บ่อยครั้งทำให้รู้สึกถึงการผลักสิ่งต่าง ๆ เข้ามาในแบบจำลองของคุณมากขึ้นทำให้ตัวควบคุมเล็กลง สิ่งนี้ทำให้มั่นใจได้ว่าตรรกะนี้สามารถใช้ได้อย่างง่ายดายจากทุกที่ที่คุณต้องการเข้าถึงข้อมูลที่โมเดลของคุณเป็นตัวแทน มุมมองไม่ควรมีตรรกะ โดยทั่วไปจริงๆแล้วคุณควรพยายามทำเพื่อที่คุณจะได้ไม่ทำซ้ำตัวเอง
นอกจากนี้ google จำนวนเล็กน้อยยังแสดงตัวอย่างที่ชัดเจนของสิ่งที่เกิดขึ้น
รุ่น: ข้อกำหนดในการตรวจสอบความสัมพันธ์ของข้อมูลวิธีการสร้างวิธีการอัปเดตวิธีทำลายวิธีค้นหา (โปรดทราบว่าคุณไม่ควรมีเพียงวิธีทั่วไปในรุ่นนี้ แต่ถ้ามีบางสิ่งที่คุณกำลังทำอยู่เช่นการค้นหาคนที่มีสีแดง เส้นผมตามนามสกุลจากนั้นคุณควรแยกตรรกะนั้นเพื่อให้สิ่งที่คุณต้องทำคือโทรหา find_redH_by_name ("smith") หรืออะไรทำนองนั้น)
มุมมอง: สิ่งนี้ควรเกี่ยวกับการจัดรูปแบบข้อมูลไม่ใช่การประมวลผลข้อมูล
ตัวควบคุม: นี่คือที่การประมวลผลข้อมูลไป จากอินเทอร์เน็ต: "วัตถุประสงค์ของคอนโทรลเลอร์คือเพื่อตอบสนองต่อการกระทำที่ผู้ใช้ร้องขอใช้พารามิเตอร์ใด ๆ ที่ผู้ใช้ตั้งค่าประมวลผลข้อมูลโต้ตอบกับรุ่นแล้วส่งข้อมูลที่ร้องขอในรูปแบบสุดท้ายออกไป ดู."
หวังว่าจะช่วย
กล่าวโดยทั่วไปแล้ว แบบจำลองจะมีรหัสทั้งหมดที่เกี่ยวข้องกับตารางความสัมพันธ์ที่เรียบง่ายหรือซับซ้อน (คิดว่าพวกเขาเป็นแบบสอบถาม SQL ที่เกี่ยวข้องกับหลายตาราง) การจัดการข้อมูล / ตัวแปรเพื่อให้ได้ผลลัพธ์โดยใช้ตรรกะทางธุรกิจ .
ตัวควบคุมจะมีรหัส / ตัวชี้ไปยังโมเดลที่เกี่ยวข้องสำหรับงานที่ร้องขอ
มุมมองจะยอมรับอินพุต / การโต้ตอบของผู้ใช้และแสดงการตอบสนองผลลัพธ์
การเบี่ยงเบนที่สำคัญจากสิ่งเหล่านี้จะสร้างความเครียดที่ไม่พึงประสงค์ในส่วนนั้นและประสิทธิภาพโดยรวมของแอปพลิเคชันอาจได้รับผลกระทบ
การทดสอบการทดสอบ ... ใส่ตรรกะให้มากที่สุดเท่าที่จะทำได้ในโมเดลจากนั้นคุณจะสามารถทดสอบได้อย่างถูกต้อง การทดสอบหน่วยทดสอบข้อมูลและวิธีการสร้างโดยการทดสอบแบบจำลองและการทดสอบการทำงานทดสอบวิธีการกำหนดเส้นทางหรือควบคุมโดยการทดสอบตัวควบคุมดังนั้นจึงเป็นไปตามที่คุณไม่สามารถทดสอบความสมบูรณ์ของข้อมูลเว้นแต่จะอยู่ใน นางแบบ.
J