ตรวจสอบให้แน่ใจว่าแต่ละชั้นเรียนมีเพียงความรับผิดชอบเดียวทำไม?


37

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

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



1
ฉันมีคำถามที่คุณอาจพบว่าเกี่ยวข้องด้วย: อะไรคือความรับผิดชอบที่แท้จริงของชั้นเรียน
Pierre Arlaud

3
เหตุผลทั้งหมดของความรับผิดชอบเดี่ยวไม่ถูกต้องใช่ไหม มันทำให้การบำรุงรักษาง่ายขึ้น มันทำให้การทดสอบง่ายขึ้น มันทำให้คลาสแข็งแกร่งขึ้น (โดยทั่วไป)
Martin York

2
ด้วยเหตุผลเดียวกันกับที่คุณมีคลาส AT ทั้งหมด
Davor Ždralo

2
ฉันมักจะมีปัญหากับคำสั่งนี้ มันยากมากที่จะกำหนดว่า "ความรับผิดชอบเดียว" คืออะไร ความรับผิดชอบเดียวสามารถช่วงใดก็ได้จาก "ตรวจสอบว่า 1 + 1 = 2" ถึง "เก็บรักษาบันทึกที่ถูกต้องของเงินทั้งหมดที่จ่ายเข้าและออกจากบัญชีธนาคารขององค์กร"
Dave Nay

คำตอบ:


57

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

SRP นั้นใช้ได้กับฟังก์ชั่นเหมือนกับคลาส แต่ภาษา OOP หลักนั้นค่อนข้างจะยากจนเมื่อฟังก์ชั่นติดกาวเข้าด้วยกัน


12
+1 สำหรับการกล่าวถึงการเขียนโปรแกรมการทำงานเป็นวิธีที่ปลอดภัยกว่าในการเขียน abstractions
logc

> แต่ภาษา OOP หลักค่อนข้างยากจนเมื่อฟังก์ชั่นติดกาวเข้าด้วยกัน <อาจเป็นเพราะภาษา OOP ไม่ได้เกี่ยวข้องกับฟังก์ชั่น แต่เป็นข้อความ
Jeff Hubbard

@JeffHubbard ฉันคิดว่าคุณหมายความว่าเป็นเพราะพวกเขาทำตาม C / C ++ ไม่มีอะไรเกี่ยวกับวัตถุที่ทำให้มันไม่สามารถใช้ร่วมกับฟังก์ชั่นได้ นรกวัตถุ / ส่วนต่อประสานเป็นเพียงบันทึก / โครงสร้างของฟังก์ชั่น การเสแสร้งฟังก์ชั่นไม่ใช่เรื่องสำคัญทั้งในทางทฤษฎีและในทางปฏิบัติ พวกเขาไม่สามารถหลีกเลี่ยงได้ - คุณต้องทิ้ง "Runnables", "โรงงาน", "ผู้ให้บริการ" และ "การกระทำ" หรือใช้รูปแบบ "กลยุทธ์" และกลยุทธ์ที่เรียกว่า "และจบลงด้วย กลุ่มของแผ่นสำเร็จรูปที่ไม่จำเป็นเพื่อให้งานเดียวกันเสร็จ
Doval

@Doval ไม่ฉันหมายความว่า OOP เกี่ยวข้องกับข้อความจริงๆ ที่ไม่ได้บอกว่าเป็นภาษาที่ได้รับจะดีกว่าหรือเลวร้ายยิ่งกว่าการเขียนโปรแกรมภาษาทำงานที่ติดกาวฟังก์ชั่นร่วมกัน - เพียงแค่ว่ามันไม่ได้เป็นความกังวลหลักของภาษา
Jeff Hubbard

โดยทั่วไปถ้าภาษาของคุณเกี่ยวกับการทำให้ OOP ง่ายขึ้น / ดีขึ้น / เร็วขึ้น / มากขึ้นแสดงว่าการทำงานของกาวเข้าด้วยกันอย่างดีหรือไม่นั้นไม่ใช่สิ่งที่คุณมุ่งเน้น
Jeff Hubbard

30

การบำรุงรักษาที่ดีกว่าการทดสอบง่ายการแก้ไขข้อผิดพลาดที่เร็วขึ้นเป็นเพียงผลลัพธ์ที่น่าพอใจในการใช้ SRP เหตุผลหลัก (ตามที่โรเบิร์ตซี. Matin วางไว้) คือ:

คลาสควรมีเหตุผลเดียวเท่านั้นที่จะมีการเปลี่ยนแปลง

ในคำอื่น ๆSRP ยกเปลี่ยนแปลงท้องที่

SRP ยังส่งเสริมรหัส DRY ตราบใดที่เรามีคลาสที่มีเพียงความรับผิดชอบเดียวเราอาจเลือกที่จะใช้ในทุกที่ที่เราต้องการ หากเรามีชั้นเรียนที่มีความรับผิดชอบสองอย่าง แต่เราต้องการเพียงหนึ่งในนั้นและอย่างที่สองก็รบกวนเรามี 2 ตัวเลือก:

  1. คัดลอกวางชั้นเรียนลงในที่อื่นและอาจสร้างการกลายพันธุ์ที่รับผิดชอบหลายอย่างอีกครั้ง (เพิ่มหนี้ทางเทคนิคเล็กน้อย)
  2. แบ่งชั้นเรียนและทำให้มันเป็นตามที่ควรจะเป็นในสถานที่แรกซึ่งอาจมีราคาแพงเนื่องจากการใช้งานที่กว้างขวางของชั้นเรียนเดิม

1
+1 สำหรับการเชื่อมโยง SRP กับ DRY
มาห์ดี

21

ง่ายต่อการสร้างรหัสเพื่อแก้ไขปัญหาเฉพาะ มีความซับซ้อนมากขึ้นในการสร้างรหัสที่แก้ไขปัญหาในขณะที่อนุญาตให้ทำการเปลี่ยนแปลงในภายหลังได้อย่างปลอดภัย SOLID จัดเตรียมชุดของการปฏิบัติที่ทำให้โค้ดดีขึ้น

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

ตามความหมาย:

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

ลองสร้างรหัสในขณะที่ปฏิบัติตามหลักการและทบทวนรหัสนั้นอีกครั้งในภายหลังเพื่อทำการเปลี่ยนแปลงบางอย่าง คุณจะเห็นข้อได้เปรียบมหาศาลที่มีให้

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


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

2
คุณทำเช่นเดียวกันกับทุกคลาส คุณจบด้วยคลาสเพิ่มเติมทั้งหมดปฏิบัติตาม SRP มันทำให้โครงสร้างมีความซับซ้อนมากขึ้นจากมุมมองของการเชื่อมต่อ แต่ความเรียบง่ายในแต่ละชั้นนั้น ฉันชอบคำตอบของ @ Doval
Miyamoto Akira

ฉันคิดว่าคุณควรเพิ่มคำตอบของคุณ

4

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

  • การบำรุงรักษาที่ดีกว่า : ในอุดมคติเมื่อใดก็ตามที่ฟังก์ชั่นการทำงานของระบบมีการเปลี่ยนแปลงจะมีคลาสเพียงคลาสเดียวเท่านั้นที่ต้องเปลี่ยน การแมปที่ชัดเจนระหว่างคลาสและความรับผิดชอบหมายความว่านักพัฒนาที่เกี่ยวข้องในโครงการสามารถระบุคลาสนี้ได้ (ดังที่ @ MaciejChałapukได้สังเกตดูRobert C. Martin, "Clean Code" )

  • การทดสอบที่ง่ายขึ้น : โดยพื้นฐานแล้วคลาสควรมีส่วนต่อประสานสาธารณะน้อยที่สุดเท่าที่จะทำได้และการทดสอบควรเน้นเฉพาะส่วนต่อประสานสาธารณะนี้ หากคุณไม่สามารถทดสอบด้วยความชัดเจนได้เนื่องจากหลายส่วนในชั้นเรียนของคุณเป็นแบบส่วนตัวนี่เป็นสัญญาณที่ชัดเจนว่าชั้นเรียนของคุณมีความรับผิดชอบมากเกินไปและคุณควรแยกมันออกเป็นคลาสย่อยที่เล็กกว่า โปรดสังเกตว่าสิ่งนี้ใช้กับภาษาที่ไม่มีสมาชิกชั้น 'สาธารณะ' หรือ 'ส่วนตัว' การมีอินเตอร์เฟสสาธารณะขนาดเล็กหมายความว่ามีความชัดเจนในรหัสลูกค้าซึ่งเป็นส่วนหนึ่งของคลาสที่ควรใช้ (ดูKent Beck, "การพัฒนาทดสอบขับเคลื่อน"สำหรับรายละเอียดเพิ่มเติม)

  • รหัสที่มีประสิทธิภาพ : รหัสของคุณจะไม่ล้มเหลวบ่อยขึ้นหรือน้อยลงเนื่องจากมีการเขียนที่ดี แต่เป็นรหัสทั้งหมดเป้าหมายสูงสุดของมันคือไม่ต้องสื่อสารกับเครื่องแต่กับนักพัฒนาเพื่อน (ดูKent Beck, "Implementation Patterns" , ตอนที่ 1) codebase ที่ชัดเจนนั้นง่ายกว่าที่จะให้เหตุผลเรื่องนี้ และใช้เวลาน้อยลงในการค้นหาข้อบกพร่องและแก้ไข


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

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

3

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

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

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

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

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


2

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

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


1

ฉันทำตามความคิด: 1 Class = 1 Job.

การใช้สรีรวิทยาการเปรียบเทียบ: มอเตอร์ (ระบบประสาท), ระบบหายใจ (ปอด), ระบบย่อยอาหาร (กระเพาะอาหาร), การดมกลิ่น (การสังเกต) ฯลฯ แต่ละเหล่านี้จะมีชุดควบคุม แต่พวกเขาแต่ละคนมีความรับผิดชอบเพียง 1 อย่างเท่านั้น วิธีที่ระบบย่อยแต่ละระบบทำงานหรือว่าเป็นระบบย่อยจุดปลายและทำงานเพียง 1 งานเช่นการยกนิ้วหรือการปลูกรากผม

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

ส่วนที่ซับซ้อนที่สุดของสิ่งที่ฉันมีประสบการณ์คือรู้ว่าเมื่อใดที่จะกำหนด Class เป็น Operator, Supervisor หรือกระบวนการ Manager ไม่ว่าคุณจะต้องสังเกตและแสดงการทำงานของมันสำหรับความรับผิดชอบ 1 อย่าง (ผู้ปฏิบัติงานหัวหน้างานหรือผู้จัดการ)

เมื่อคลาส / วัตถุมีบทบาทประเภทเหล่านี้มากกว่า 1 บทบาทคุณจะพบว่ากระบวนการโดยรวมจะเริ่มมีปัญหาด้านประสิทธิภาพหรือกระบวนการคอขวด


แม้ว่าการจัดการการใช้ออกซิเจนในบรรยากาศลงในฮีโมโกลบินนั้นควรได้รับการจัดการในLungชั้นเรียน แต่ฉันก็ยังคงวางตัวอย่างที่Personควรจะเป็นBreatheดังนั้นPersonชั้นควรมีเหตุผลเพียงพอที่จะมอบหมายความรับผิดชอบที่เกี่ยวข้องกับวิธีการนั้นให้น้อยที่สุด ฉันขอแนะนำเพิ่มเติมว่าฟอเรสต์ของเอนทิตีที่เชื่อมต่อกันซึ่งเข้าถึงได้โดยเจ้าของทั่วไปมักจะง่ายกว่าที่จะให้เหตุผลมากกว่าฟอเรสต์ที่มีจุดเชื่อมต่ออิสระหลายแห่ง
supercat

ใช่ในกรณีนี้ลุงเป็นผู้จัดการแม้ว่า Villi จะเป็นหัวหน้างานและกระบวนการของการหายใจจะเป็นระดับคนงานเพื่อถ่ายโอนอนุภาคอากาศไปยังกระแสเลือด
โกลด์บิชอป

@ GoldBishop: บางทีมุมมองที่ถูกต้องน่าจะพูดได้ว่าPersonคลาสมีหน้าที่แทนการทำงานทั้งหมดที่เกี่ยวข้องกับเอนทิตี้ของ "โลกแห่งความเป็นมนุษย์ - มนุษย์" ที่ซับซ้อนอย่างยิ่งยวดรวมถึงความสัมพันธ์ของส่วนต่างๆ . การมีเอนทิตีทำสิ่งต่าง ๆ 500 อย่างน่าเกลียด แต่ถ้านั่นเป็นวิธีที่ระบบโลกแห่งความจริงเป็นแบบจำลองการทำงานการมีคลาสที่มอบหมายหน้าที่ 500 ฟังก์ชั่นในขณะที่การรักษาเอกลักษณ์หนึ่งตัวอาจดีกว่าการทำทุกอย่างด้วยชิ้นส่วนที่ไม่ปะติดปะต่อ
supercat

@supercat หรือคุณสามารถรวมสิ่งทั้งหมดเข้าด้วยกันและมี 1 คลาสกับหัวหน้างานที่จำเป็นเหนือกระบวนการย่อย ด้วยวิธีนี้คุณสามารถ (ในทางทฤษฎี) แต่ละกระบวนการแยกจากระดับฐานPersonแต่ยังรายงานถึงความสำเร็จ / ความล้มเหลว แต่ไม่จำเป็นต้องส่งผลกระทบต่อกระบวนการอื่น ฟังก์ชั่น 500 ฟังก์ชั่น (แม้ว่าจะถูกตั้งค่าไว้เป็นตัวอย่างจะเกินน้ำและไม่รองรับ) ฉันพยายามที่จะรักษาฟังก์ชั่นที่ได้รับและโมดูลาร์
โกลด์บิชอป

@ GoldBishop: ฉันหวังว่าจะมีวิธีที่จะประกาศประเภท "ephemeral" เช่นรหัสภายนอกสามารถเรียกสมาชิกเมื่อมันหรือผ่านมันเป็นพารามิเตอร์ให้กับวิธีการของตัวเองประเภท แต่ไม่มีอะไรอื่น จากมุมมองขององค์กรรหัสชั้นเรียนแบ่งทำให้ความรู้สึกและไม่ต้องมีรหัสนอกเรียกวิธีหนึ่งระดับลง (เช่นFred.vision.lookAt(George)ทำให้รู้สึก แต่อนุญาตให้ใช้รหัสที่จะบอกว่าsomeEyes = Fred.vision; someTubes = Fred.digestionดูเหมือนว่าเหนอะเพราะมันปิดบังความสัมพันธ์ระหว่างsomeEyesและsomeTubes.
SuperCat

1

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

เหตุผลบางอย่างอาจเป็น:

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

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


... test is not affected by other responsibilities the class hasคุณช่วยอธิบายเรื่องนี้ได้ไหม
มาห์ดี

1

วิธีที่ดีที่สุดในการเข้าใจถึงความสำคัญของหลักการเหล่านี้คือการมีความต้องการ

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

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

คุณไม่สามารถเข้าใจความสำคัญของรูปแบบการออกแบบได้จนกว่าจะมีความจำเป็นเกิดขึ้น ฉันเคารพรูปแบบเพราะจากประสบการณ์ที่ฉันสามารถพูดได้พวกเขาทำให้การบำรุงรักษารหัสง่ายและมีประสิทธิภาพของรหัส

อย่างไรก็ตามเช่นเดียวกับคุณฉันยังคงไม่แน่ใจเกี่ยวกับ "การทดสอบอย่างง่าย" เพราะฉันยังไม่จำเป็นต้องทดสอบหน่วย


รูปแบบเชื่อมต่อกับ SRP แต่ไม่จำเป็นต้องใช้ SRP เมื่อใช้รูปแบบการออกแบบ เป็นไปได้ที่จะใช้รูปแบบและไม่สนใจ SRP อย่างสมบูรณ์ เราใช้รูปแบบเพื่อจัดการกับข้อกำหนดที่ไม่สามารถใช้งานได้ แต่ไม่จำเป็นต้องใช้รูปแบบในโปรแกรมใด ๆ หลักการมีความสำคัญในการทำให้การพัฒนาน้อยลงเจ็บปวดและ (IMO) ควรเป็นนิสัย
Maciej Chałapuk

ฉันเห็นด้วยกับคุณ. SRP ในบางระดับบังคับให้ทำความสะอาดการออกแบบวัตถุและลำดับชั้น มันเป็นความคิดที่ดีสำหรับนักพัฒนาที่จะเข้ามาเพราะจะทำให้นักพัฒนาเริ่มคิดในแง่ของวัตถุและวิธีที่พวกเขาควรจะเป็น โดยส่วนตัวแล้วมันมีผลดีกับการพัฒนาของฉันเช่นกัน
harsimranb

1

คำตอบคือตามที่คนอื่นชี้ให้เห็นพวกเขาทั้งหมดถูกต้องและพวกเขาทั้งหมดฟีดเข้าด้วยกันง่ายต่อการทดสอบทำให้การบำรุงรักษาง่ายขึ้นทำให้รหัสแข็งแกร่งขึ้นทำให้การบำรุงรักษาง่ายขึ้นและอื่น ๆ ...

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

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

ขอบเขตที่ขยายได้ = ความซับซ้อนมากขึ้น = วิธีอื่น ๆ ที่ผิดพลาด


1

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

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

แต่มีกฎง่ายๆของ“เพียงคนเดียวที่รับผิดชอบ” เพียงแค่ทำให้มันง่ายที่จะรู้ว่าเมื่อคุณต้องเรียนใหม่

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

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