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


34

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

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



คำตอบ:


21

ทำไมใช่มันเป็นอัตนัยมากและเป็นเรื่องของโปรแกรมเมอร์จำนวนมากที่มีปัญหา

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

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


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

13

Bob Martin (ลุง Bob) ผู้ริเริ่มหลักการSOLIDที่SRPเป็นคนแรกพูดเกี่ยวกับสิ่งนี้ (ฉันกำลังถอดความไม่สามารถจำคำที่แท้จริงได้):

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

หากมีมากกว่าหนึ่งเหตุผลก็ไม่ได้เป็นไปตาม SRP


14
นั่นเป็นเพียงการทำซ้ำคำจำกัดความจริงๆ แต่จริงๆแล้วการยึดมั่นกับ srp ยังคงเป็นเรื่องที่ค่อนข้างน่าสนใจ
Andy

7

ฉันให้กฎง่ายๆหลายข้อกับคุณได้

  • การตั้งชื่อชั้นเรียนเป็นเรื่องง่ายแค่ไหน? ถ้าคลาสยากที่จะบอกชื่อมันอาจจะทำมากเกินไป
  • ชั้นเรียนมีวิธีการสาธารณะกี่วิธี? 7 +/- 2 เป็นกฎง่ายๆ หากชั้นเรียนมีมากกว่านั้นคุณควรคิดถึงการแบ่งเป็นหลายชั้น
  • มีการใช้วิธีสาธารณะแบบกลุ่มในบริบทที่แยกกันหรือไม่
  • มีวิธีการส่วนตัวหรือข้อมูลสมาชิกกี่วิธี? หากคลาสมีโครงสร้างภายในที่ซับซ้อนคุณอาจต้องปรับโครงสร้างใหม่เพื่อให้การบรรจุภายในมีขนาดเล็กลงแยกต่างหาก
  • และกฎง่ายๆที่ง่ายที่สุด: ชั้นเรียนใหญ่แค่ไหน? หากคุณมีไฟล์ส่วนหัว C ++ ที่มีคลาสเดียวที่มีความยาวมากกว่าสองร้อยบรรทัดคุณควรแยกมันออก

2
เกี่ยวกับประเด็นที่สองของคุณโปรดดูuxmyths.com/post/931925744/…
Cameron Martin

7
ไม่เห็นด้วยอย่างยิ่งเกี่ยวกับ 7 +/- 2 - หลักการความรับผิดชอบเดียวคือเกี่ยวกับการติดต่อกันทางความหมายไม่ใช่เกี่ยวกับตัวเลขโดยพลการ
JacquesB

1
กฎของหัวแม่มือไม่จำเป็นต้องมีหลักฐานทางวิทยาศาสตร์ที่เป็นอิสระ วิธีการทางวิทยาศาสตร์ที่ทันสมัยมีอายุหลายศตวรรษสถาปัตยกรรมและวิศวกรรมมีอายุเก่าแก่นับพันปี กฎง่ายๆสำหรับวิธีสาธารณะคือ "หลาย" และไม่มีพารามิเตอร์คือ "ไม่กี่" ในข่าวอื่น ๆ ถึงแม้ว่าภาพวาดของเด็กบางคนจะแสดงมิฉะนั้นแขนของผู้คนจะไม่ออกมาจากหัวของพวกเขา
abuzittin gillifirca

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

6

หลักการความรับผิดชอบเดี่ยวกล่าวว่าแต่ละโมดูลซอฟต์แวร์ควรมีเหตุผลเดียวที่จะเปลี่ยนแปลง ในบทความล่าสุดลุงบ๊อบอธิบาย "เหตุผลในการเปลี่ยนแปลง"

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

เขาอธิบายเพิ่มเติมแนวคิดด้วยตัวอย่างที่นี่


นั่นเป็นบทความที่ยอดเยี่ยมเขียนโดยชายคนนั้นเอง
MrDustpan

4

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

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

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

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


2

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

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

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

ด้วยโครงสร้างพื้นฐานทำให้ง่ายต่อการระบุกรณีที่กฎความรับผิดชอบเดี่ยวถูกทำลาย EG ผ่านอินสแตนซ์ของ User Control ไปยัง Modal


1

เพียงเพื่อประโยชน์ของการสนทนาที่ฉันจะนำขึ้นชั้นจากJuceเรียกAudioSampleBuffer ตอนนี้คลาสนี้มีไว้เพื่อเก็บตัวอย่างข้อมูล (หรืออาจเป็นข้อมูลโค้ดที่ค่อนข้างยาว) มันรู้จำนวนช่องสัญญาณ, จำนวนตัวอย่าง (ต่อช่อง), ดูเหมือนว่าถูกกำหนดให้ลอยแบบ IEEE แบบ 32 บิตแทนที่จะมีการแสดงตัวเลขหรือตัวแปรคำพูด (แต่นั่นไม่ใช่ปัญหาของฉัน) มีฟังก์ชั่นสมาชิกที่ให้คุณรับ numChannels หรือ numSamples และพอยน์เตอร์ไปยังช่องใดช่องหนึ่งได้ คุณสามารถทำให้ AudioSampleBuffer ยาวขึ้นหรือสั้นลงได้ ฉันสันนิษฐานว่าศูนย์แผ่นรองก่อนหน้าบัฟเฟอร์ในขณะที่ตัดหลัง

มีสมาชิกส่วนตัวบางส่วนของคลาสนี้ที่ใช้สำหรับการจัดสรรพื้นที่ในฮีปพิเศษที่ JUCE ใช้

แต่นี่คือสิ่งที่ AudioSampleBuffer หายไป (และฉันได้มีการอภิปรายหลายกับจูลส์เกี่ยวกับเรื่องนี้): SampleRateเป็นสมาชิกที่เรียกว่า วิธีก็อาจจะหายไปหรือไม่?

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

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

นี่คือตัวอย่างของความล้มเหลวในการตอบสนองความรับผิดชอบเดียวของมัน


1

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

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

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