ชั้นเรียนมีหลายวิธีได้อย่างไรโดยไม่ทำลายหลักการความรับผิดชอบเดี่ยว


64

หลักการความรับผิดชอบเดี่ยวถูกกำหนดไว้บนวิกิพีเดียเป็น

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

ถ้าคลาสควรมีความรับผิดชอบเพียงอย่างเดียวมันจะมีวิธีมากกว่า 1 วิธีได้อย่างไร แต่ละวิธีจะไม่มีความรับผิดชอบแตกต่างกันซึ่งหมายความว่าชั้นเรียนจะมีความรับผิดชอบมากกว่า 1 ครั้ง

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


11
ทำไมต้องลงคะแนน ดูเหมือนว่าเป็นคำถามที่เหมาะสำหรับ SE.SE ผู้วิจัยหัวข้อและพยายามทำให้คำถามชัดเจนมาก มันสมควรได้รับ upvotes แทน
Arseni Mourzenko

19
downvote อาจเป็นเพราะนี้เป็นคำถามที่ได้รับการถามและตอบหลายครั้งแล้วเช่นเห็นsoftwareengineering.stackexchange.com/questions/345018/... ในความคิดของฉันมันไม่ได้เพิ่มแง่มุมใหม่ ๆ มากมาย
Hans-Martin Mosner


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

6
@DarrelHoffman นั่นไม่เป็นความจริง หากทุกคลาสเป็น functor ที่มีวิธี "call ()" เท่านั้นคุณก็จะจำลองการเขียนโปรแกรมแบบโพรซีเดอร์แบบธรรมดาด้วยการเขียนโปรแกรมเชิงวัตถุ คุณยังสามารถทำสิ่งใดก็ได้ที่คุณสามารถทำได้เป็นอย่างอื่นเนื่องจากเมธอด "call ()" ของคลาสสามารถเรียกเมธอด "call ()" ของคลาสอื่นได้
Vaelus

คำตอบ:


29

ความรับผิดชอบเดี่ยวอาจไม่ใช่สิ่งที่ฟังก์ชั่นเดียวสามารถเติมเต็มได้

 class Location { 
     public int getX() { 
         return x;
     } 
     public int getY() { 
         return y; 
     } 
 }

ชั้นนี้อาจทำลายหลักการความรับผิดชอบเดียว ไม่ใช่เพราะมันมีสองหน้าที่ แต่ถ้ารหัสสำหรับgetX()และgetY()ต้องตอบสนองผู้มีส่วนได้เสียที่แตกต่างกันที่อาจต้องการการเปลี่ยนแปลง หากรองประธานนาย X ส่งบันทึกช่วยจำว่าตัวเลขทั้งหมดจะแสดงเป็นตัวเลขทศนิยมและผู้อำนวยการฝ่ายบัญชีนาง Y ยืนยันว่าตัวเลขทั้งหมดที่แผนกรีวิวของเธอจะยังคงเป็นจำนวนเต็มโดยไม่คำนึงถึงสิ่งที่นายเอ็กซ์คิดว่าดี ความคิดเดียวของผู้ที่รับผิดชอบเพราะสิ่งต่าง ๆ กำลังสับสน

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

นอกเหนือจากสิ่งนั้น ไม่ได้หลายวิธีก็ใช้ได้ เพียงแค่ให้ชื่อที่ชัดเจนว่าวิธีการอยู่ในชั้นเรียนและสิ่งที่ไม่ได้

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

"โมดูลควรจะรับผิดชอบต่อหนึ่งและเพียงคนเดียวเท่านั้นที่นักแสดง"

Robert C Martin - สถาปัตยกรรมสะอาด

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

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

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

หลักการคลาสสิกที่จะใช้ที่นี่จะเรียกว่าการแยกความกังวลเกี่ยวกับ หากคุณแยกข้อกังวลทั้งหมดของคุณมันอาจเป็นที่ถกเถียงกันอยู่ว่าสิ่งที่เหลืออยู่ในที่เดียวคือข้อกังวลเดียว นั่นคือสิ่งที่เราเรียกว่าความคิดนี้ก่อนที่ภาพยนตร์ City Slickers ปี 1991 จะแนะนำเราให้รู้จักกับตัวละคร Curly

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

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

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

วิธีการใช้งานที่ใช้มองสิ่งนี้ก็คือa.f(x)และa.g(x)เป็นเพียง f a (x) และ g a (x) ไม่ใช่ฟังก์ชั่นสองอย่าง แต่เป็นคู่ของฟังก์ชั่นที่ต่อเนื่องกัน aไม่ได้จะต้องมีข้อมูลอยู่แล้ว มันอาจเป็นวิธีที่คุณรู้fและgใช้งานสิ่งที่คุณจะใช้ ฟังก์ชั่นที่เปลี่ยนแปลงด้วยกันอยู่ด้วยกัน นั่นคือความแตกต่างที่ดีเก่า

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


25
ฉันคิดว่าคำตอบนี้สร้างความสับสนให้กับคนที่พยายามคิด SRP การต่อสู้ระหว่างนายประธานาธิบดีและผู้อำนวยการนางไม่ได้รับการแก้ไขด้วยวิธีการทางเทคนิคและใช้มันเพื่อพิสูจน์ว่าการตัดสินใจทางวิศวกรรมนั้นไร้สาระ กฎหมายของคอนเวย์ในทางปฏิบัติ
whatsisname

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

กฎของลอนด์ดังที่ทิมโอตทิงเกอร์อธิบายไว้ว่าตัวแปรควรมีความหมายอย่างเดียวเสมอ สำหรับฉัน SRP นั้นแข็งแกร่งกว่านั้นเล็กน้อย คลาสสามารถแสดงถึงแนวคิด "สิ่งเดียว" ได้ แต่ยังละเมิด SRP หากไดรเวอร์ภายนอกสองการเปลี่ยนแปลงให้ความสำคัญกับ "สิ่งหนึ่ง" ในรูปแบบที่แตกต่างกันหรือเกี่ยวข้องกับสองด้านที่แตกต่างกัน ปัญหาคือหนึ่งในการสร้างแบบจำลอง คุณเลือกที่จะสร้างโมเดลเป็นคลาสเดียวกัน แต่มีบางอย่างเกี่ยวกับโดเมนที่ทำให้เกิดปัญหากับตัวเลือกนั้น (สิ่งต่าง ๆ เริ่มเข้ามาในแบบของคุณเมื่อ codebase วิวัฒนาการขึ้นมา)
Filip Milovanović

2
@ FilipMilovanovićความคล้ายคลึงกันที่ฉันเห็นระหว่าง Conway's Law กับ SRP คือวิธีที่ลุง Bob อธิบาย SRP ในหนังสือ Clean Architecture ของเขามาจากการสันนิษฐานว่าองค์กรมีแผนภูมิองค์กรที่สะอาด นี่เป็นความคิดเก่า แม้แต่พระคัมภีร์ก็มีคำพูดที่นี่: "ไม่มีใครสามารถรับใช้เจ้านายสองคน"
candied_orange

1
@TKK ฉันเกี่ยวข้องกับมัน (ไม่เท่ากัน) กับกฎหมายของ Conways ไม่ใช่กฎของลอนด์ ฉันกำลังหักล้างความคิดที่ว่า SRP เป็นกฎของลอนส่วนใหญ่เพราะลุงบ๊อบพูดในหนังสือ Clean Architecture ของเขา
candied_orange

48

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

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

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

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

ทีนี้วิธีการทั้งหมดนั้นมีเป้าหมายเดียวเหมือนกันคือรับลำดับและสร้าง CSV นี้เป็นความรับผิดชอบเดียวของชั้น


Pablo Hแสดงความคิดเห็น:

ตัวอย่างที่ดี แต่ฉันรู้สึกว่ามันยังไม่ตอบว่าทำไม SRP อนุญาตให้คลาสมีวิธีสาธารณะมากกว่าหนึ่งวิธี

จริง ตัวอย่าง CSV ที่ฉันให้มีวิธีสาธารณะหนึ่งวิธีและวิธีอื่น ๆ ทั้งหมดเป็นส่วนตัว ตัวอย่างที่ดีกว่าน่าจะเป็นของคิวที่นำมาใช้โดยQueueคลาส คลาสนี้จะมีสองวิธีโดยพื้นฐาน: push(เรียกอีกอย่างว่าenqueue) และpop(เรียกอีกอย่างว่าdequeue)

  • ความรับผิดชอบของQueue.pushคือการเพิ่มวัตถุไปยังหางของคิว

  • ความรับผิดชอบของQueue.popคือการลบวัตถุออกจากหัวของคิวและจัดการกรณีที่คิวว่างเปล่า

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


1
ตัวอย่างที่ดี แต่ฉันรู้สึกว่ามันยังไม่ตอบว่าทำไม SRP อนุญาตให้คลาสมีวิธีสาธารณะมากกว่าหนึ่งวิธี
Pablo H

1
@PabloH: ยุติธรรม ฉันได้เพิ่มอีกตัวอย่างหนึ่งซึ่งคลาสมีสองวิธี
Arseni Mourzenko

30

ฟังก์ชั่นเป็นฟังก์ชั่น

ความรับผิดชอบเป็นความรับผิดชอบ

ช่างมีความรับผิดชอบในการซ่อมรถยนต์ซึ่งจะเกี่ยวข้องกับการวินิจฉัยงานบำรุงรักษาง่าย ๆ งานซ่อมจริงงานมอบหมายงานให้ผู้อื่น ฯลฯ

คลาสคอนเทนเนอร์ (รายการอาร์เรย์พจนานุกรมแผนที่ ฯลฯ ) มีหน้าที่จัดเก็บวัตถุซึ่งเกี่ยวข้องกับการจัดเก็บการอนุญาตการแทรกการเข้าถึงการสั่งซื้อบางประเภท ฯลฯ

ความรับผิดชอบเดียวไม่ได้หมายความว่ามีรหัส / ฟังก์ชันน้อยมาก แต่หมายถึงฟังก์ชันใดก็ตามที่มี "เป็นของกัน" ภายใต้ความรับผิดชอบเดียวกัน


2
เห็นพ้อง @Aulis Ronkainen - ผูกสองคำตอบ และสำหรับความรับผิดชอบที่ซ้อนกันโดยใช้กลไกการเปรียบเทียบของคุณอู่ซ่อมรถมีหน้าที่รับผิดชอบในการบำรุงรักษายานพาหนะ กลไกที่แตกต่างกันในโรงรถมีความรับผิดชอบในส่วนต่าง ๆ ของรถ แต่กลไกเหล่านี้ทำงานร่วมกันในการทำงานร่วมกัน
wolfsshield

2
@wolfsshield เห็นด้วย ช่างที่ทำสิ่งหนึ่งเพียงอย่างเดียวนั้นไร้ประโยชน์ แต่ช่างที่มีความรับผิดชอบเพียงอย่างเดียวนั้นไม่ได้เป็นอย่างน้อย ถึงแม้ว่าการใช้งานจริงในชีวิตประจำวันจะไม่ดีที่สุดในการอธิบายแนวคิด OOP ที่เป็นนามธรรม แต่ก็เป็นสิ่งสำคัญที่จะต้องแยกแยะความแตกต่างเหล่านี้ ฉันเชื่อว่าการไม่เข้าใจความแตกต่างคือสิ่งที่สร้างความสับสนตั้งแต่แรก
Aulis Ronkainen

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

20

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

ยกตัวอย่างเช่นคลาสบริการผู้ใช้:

class UserService {
    public User Get(int id) { /* ... */ }
    public User[] List() { /* ... */ }

    public bool Create(User u) { /* ... */ }
    public bool Exists(int id) { /* ... */ }
    public bool Update(User u) { /* ... */ }
}

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

SRP ไม่ควรสับสนกับ "หลักการแยกส่วนต่อประสาน" (ดูSOLID ) หลักการแบ่งแยกส่วนต่อประสาน (ISP) กล่าวว่าส่วนต่อประสานที่มีน้ำหนักเบาและมีขนาดเล็กนั้นเป็นสิ่งที่ดีกว่าสำหรับส่วนต่อประสานทั่วไปที่ใหญ่กว่า Go ทำให้การใช้งาน ISP อย่างหนักตลอดทั้งไลบรารีมาตรฐาน:

// Interface to read bytes from a stream
type Reader interface {
    Read(p []byte) (n int, err error)
}

// Interface to write bytes to a stream
type Writer interface {
    Write(p []byte) (n int, err error)
}

// Interface to convert an object into JSON
type Marshaler interface {
    MarshalJSON() ([]byte, error)
}

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

ขอบคุณ Luaan ที่ชี้ให้เห็นความแตกต่างระหว่าง ISP และ SRP


3
ที่จริงแล้วคุณกำลังอธิบายหลักการแยกอินเทอร์เฟซ ("ฉัน" ใน SOLID) SRP นั้นค่อนข้างต่างออกไป
Luaan

คุณใช้อนุสัญญาการเข้ารหัสฉบับใดในที่นี้ ฉันจะคาดหวังว่าวัตถุ UserServiceและUserจะได้รับการ UpperCamelCase แต่วิธีการ Create , ExistsและUpdateฉันจะได้ทำ lowerCamelCase
KlaymenDK

1
@KlaymenDK คุณพูดถูกตัวพิมพ์ใหญ่เป็นเพียงนิสัยในการใช้งาน Go (ตัวพิมพ์ใหญ่ = ส่งออก / สาธารณะตัวพิมพ์เล็ก = ส่วนตัว)
Jesse

@ Luaan ขอบคุณที่ชี้ให้เห็นว่าฉันจะชี้แจงคำตอบของฉัน
Jesse

1
@KlaymenDK หลายภาษาใช้ PascalCase สำหรับวิธีการและคลาส เช่น C #
Omegastick

15

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

ถ้าคุณขอให้พ่อครัวทำเงินเดือนด้วยนั่นคือเมื่อคุณละเมิด SRP


4

ตัวนับตัวอย่าง: การจัดเก็บสถานะที่ไม่แน่นอน

intสมมติว่าคุณมีระดับที่ง่ายที่สุดเท่าที่เคยมีงานเดียวคือการจัดเก็บ

public class State {
    private int i;


    public State(int i) { this.i = i; }
}

หากคุณถูก จำกัด เพียง 1 วิธีคุณสามารถมีsetState()หรือ a getState()ยกเว้นว่าคุณจะหยุดการห่อหุ้มและทำให้เป็นiสาธารณะ

  • สุนัขเซทเทอร์ไร้ประโยชน์โดยไม่มีทะเยอทะยาน (คุณไม่สามารถอ่านข้อมูลได้)
  • ผู้ทะเยอทะยานไร้ประโยชน์โดยไม่มีตัวตั้งค่า (คุณไม่สามารถเปลี่ยนแปลงข้อมูลได้)

ชัดเจนความรับผิดชอบเดียวนี้จำเป็นต้องมีอย่างน้อย 2 วิธีในชั้นนี้ QED


4

คุณตีความหลักการความรับผิดชอบเดี่ยวผิด ๆ

ความรับผิดชอบเดี่ยวไม่เท่ากับวิธีการเดียว พวกเขาหมายถึงสิ่งต่าง ๆ ในการพัฒนาซอฟแวร์ที่เราพูดคุยเกี่ยวกับการทำงานร่วมกัน ฟังก์ชั่น (วิธีการ) ที่มีการรวมตัวกันสูง "เป็น" ร่วมกันและสามารถนับได้ว่าเป็นการทำหน้าที่เดียว

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


2

บ่อยครั้งเป็นประโยชน์ (ในภาษาใดก็ได้โดยเฉพาะอย่างยิ่งในภาษา OO) เพื่อดูสิ่งต่าง ๆ และจัดระเบียบพวกเขาจากมุมมองของข้อมูลมากกว่าฟังก์ชั่น

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

และโดยเฉพาะอย่างยิ่งคลาสไม่ควรเปิดเผยสิ่งใดที่อาจส่งผลให้เกิดข้อมูลที่ไม่สอดคล้องกันหรือไม่ถูกต้อง ตัวอย่างเช่นหากPointต้องอยู่ภายในระนาบ (0,0) ถึง (127,127) ตัวสร้างและวิธีการใด ๆ ที่แก้ไขหรือสร้างใหม่Pointมีหน้าที่ตรวจสอบค่าที่พวกเขาได้รับและปฏิเสธการเปลี่ยนแปลงใด ๆ ที่จะละเมิดสิ่งนี้ ความต้องการ (บ่อยครั้งสิ่งที่ต้องการPointจะไม่เปลี่ยนรูปและทำให้มั่นใจว่าไม่มีวิธีการแก้ไขPointหลังจากสร้างแล้วก็จะเป็น responsbility ของชั้นเรียน)

โปรดทราบว่าการฝังรากลึกที่นี่เป็นที่ยอมรับอย่างสมบูรณ์ คุณอาจมีPointชั้นเรียนสำหรับจัดการกับคะแนนของแต่ละบุคคลและPolygonชั้นเรียนสำหรับจัดการกับชุดของPoint; สิ่งเหล่านี้ยังคงมีความรับผิดชอบแยกจากกันเนื่องจากPolygonมอบหมายความรับผิดชอบทั้งหมดสำหรับการจัดการกับสิ่งใด ๆ ที่เกี่ยวข้องกับPoint(เช่นการทำให้มั่นใจว่าประเด็นมีทั้งค่าxและyคุณค่า) ต่อPointชั้นเรียน

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