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


63

วันนี้ฉันมีข้อโต้แย้งกับใครบางคน

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

public class Employee
{
    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastname;
    }

    public string FirstName { get private set; }
    public string LastName { get; private set;}
    public int CountPaidDaysOffGranted { get; private set;}

    public void AddPaidDaysOffGranted(int numberOfdays)
    {
        // Do stuff
    }
}

หนึ่งในข้อโต้แย้งของเขาคือ: "ฉันเป็นผู้ศรัทธาในSOLIDคุณกำลังละเมิดหลักการความรับผิดชอบเดียว (SRP) เนื่องจากคุณเป็นทั้งข้อมูลและการใช้ตรรกะในชั้นเรียนเดียวกัน"

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

ฉันตัดสินใจที่จะไม่ตอบข้อโต้แย้งมากมายของเขา แต่ฉันอยากรู้ว่าชุมชนคิดอย่างไรกับคำถามนี้

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

คุณจะพูดอะไร

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


19
คลาสนี้ละเมิด SRPไม่ใช่เพราะมันเป็นการผสมข้อมูลกับตรรกะ แต่เพราะมันมีการติดต่อที่ต่ำ - วัตถุที่
ริ้น

1
วัตถุประสงค์อะไรคือการเพิ่มวันหยุดให้กับพนักงาน? ควรมีคลาสปฏิทินหรือสิ่งที่มีวันหยุด ฉันคิดว่าเพื่อนของคุณพูดถูก
James Black

9
อย่าฟังใครสักคนที่พูดว่า "ฉันเป็นผู้เชื่อใน X"
เฮมเมอร์

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

2
+1 สำหรับการเขียนโปรแกรมฟังก์ชั่นเป็นหนทางเดียวสู่สวรรค์
erip

คำตอบ:


68

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

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


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

41

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

เนื่องจากคลาสนี้มีข้อตกลงกับEmployeeฉันคิดว่ามันยุติธรรมที่จะบอกว่ามันไม่ได้ละเมิด SRP โจ๋งครึ่ม แต่คนมักจะมีความคิดเห็นของตัวเอง

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


20

ในใจของฉันชั้นนี้อาจจะละเมิด SRP ถ้ามันยังคงเป็นตัวแทนของทั้งสองและEmployeeEmployeeHolidays

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


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

1
@NiklasH เห็นด้วย Tho ส่วนตัวผมจะไม่มองแบบสุ่มและพยายามเดาชั้นฉันจะค้นหาด้วยสตูดิโอสำหรับคำว่า "หยุด" และดูสิ่งที่เรียนมันขึ้นมา :).
NikolaiDante

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

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

20

มีคำตอบที่ดีอยู่แล้วที่ชี้ให้เห็นว่า SRP เป็นแนวคิดที่เป็นนามธรรมเกี่ยวกับฟังก์ชันการทำงานแบบลอจิคัล แต่มีจุดย่อยที่ฉันคิดว่ามีมูลค่าเพิ่ม

ตัวอักษรสองตัวแรกใน SOLID, SRP และ OCP เป็นทั้งเกี่ยวกับวิธีการที่รหัสของคุณเปลี่ยนแปลงในการตอบสนองต่อการเปลี่ยนแปลงข้อกำหนด คำจำกัดความที่ชื่นชอบของ SRP คือ: "โมดูล / คลาส / ฟังก์ชั่นควรมีเหตุผลเดียวที่จะเปลี่ยน" การโต้เถียงเกี่ยวกับสาเหตุที่ทำให้รหัสของคุณเปลี่ยนนั้นมีประสิทธิผลมากกว่าการโต้เถียงว่ารหัสของคุณนั้นเป็นของแข็งหรือไม่

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

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

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


9

การที่คลาสแสดงข้อมูลไม่ใช่ความรับผิดชอบของคลาส แต่เป็นรายละเอียดการใช้งานส่วนตัว

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

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


สายการคิดที่น่าสนใจขอบคุณมากสำหรับการแบ่งปัน
tobiak777

ดี - วิธีที่ดีในการแสดงเป้าหมายที่ต้องการของ OOP
user949300

5

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

เป็นเพราะตัวตนของพนักงานผสมผสานกับการจัดการวันหยุดซึ่งไม่ดี ข้อมูลประจำตัวของพนักงานเป็นสิ่งที่ซับซ้อนที่ต้องติดตามวันหยุดพักผ่อนเงินเดือนค่าล่วงเวลาเพื่อเป็นตัวแทนของทีมที่จะเชื่อมโยงไปยังรายงานผลการปฏิบัติงาน ฯลฯ พนักงานยังสามารถเปลี่ยนชื่อนามสกุลหรือทั้งสองอย่างและยังคงเหมือนเดิม ลูกจ้าง พนักงานอาจมีการสะกดชื่อหลายชื่อเช่น ASCII และการสะกดคำแบบ Unicode คนสามารถมี 0 ถึง n ชื่อและ / หรือนามสกุล พวกเขาอาจมีชื่อแตกต่างกันในเขตอำนาจศาลที่แตกต่างกัน การติดตามตัวตนของพนักงานนั้นเป็นความรับผิดชอบที่เพียงพอที่การจัดการวันหยุดหรือวันหยุดไม่สามารถเพิ่มไว้ด้านบนโดยไม่เรียกมันว่าเป็นความรับผิดชอบที่สอง


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

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

3

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

ฉันไม่เห็นด้วยกับสิ่งนี้เหมือนกับคนอื่น ๆ

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


No! SRP ไม่ได้ถูกละเมิดโดยตรรกะหลายชิ้น, ข้อมูลหลายชิ้นหรือทั้งสองอย่างรวมกัน ข้อกำหนดเพียงอย่างเดียวคือวัตถุควรยึดตามวัตถุประสงค์ วัตถุประสงค์มีแนวโน้มที่จะนำมาซึ่งการดำเนินงานจำนวนมาก
Martin Maat

@MartinMaat: การดำเนินการจำนวนมากใช่ ตรรกะหนึ่งชิ้นเป็นผล ฉันคิดว่าเรากำลังพูดในสิ่งเดียวกัน แต่มีเงื่อนไขที่แตกต่างกัน (และฉันยินดีที่จะคิดว่าคุณเป็นคนที่ถูกต้องเพราะฉันไม่ได้ศึกษาสิ่งนี้บ่อย)
Lightness Races ใน Orbit

2

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

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

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

สำหรับความน่าจะเป็นที่จะต้องมีการเปลี่ยนแปลงนั่นคือ:

  1. การทดสอบที่ดี (ปรับปรุงความน่าเชื่อถือ)
  2. เกี่ยวข้องกับรหัสขั้นต่ำเปล่าที่จำเป็นในการทำสิ่งที่เฉพาะเจาะจง (ซึ่งอาจรวมถึงการลดข้อต่อ afferent)
  3. เพียงทำโค้ด badass ในสิ่งที่มันทำ (ดู Make หลักการ Badass)

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

Make Badass Principle: คลาสที่ใช้ในหลาย ๆ สถานที่ควรจะยอดเยี่ยม พวกเขาควรจะเชื่อถือได้มีประสิทธิภาพหากเกี่ยวข้องกับคุณภาพเป็นต้น

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

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

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

class Float
{
public:
    explicit Float(float val);
    float get() const;
    void set(float new_val);
};

ที่จริงไม่มีเหตุผลที่จะเปลี่ยน! มันดีกว่า SRP มัน ZRP!

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

แน่นอนว่าสิ่งที่เป็น TMI ก็ไม่ดีเช่นกัน เราอาจใส่ซอฟต์แวร์ทั้งหมดของเราเป็นหนึ่งคลาส มันสามารถทำได้เพียงrunวิธีเดียว และบางคนอาจโต้แย้งว่าตอนนี้มันมีเหตุผลที่กว้างมากที่จะเปลี่ยน: "คลาสนี้จะต้องมีการเปลี่ยนแปลงหากซอฟต์แวร์ต้องการการปรับปรุง" ฉันโง่ แต่แน่นอนว่าเราสามารถจินตนาการถึงปัญหาการบำรุงรักษาทั้งหมดได้

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


1

ในทางตรงกันข้ามสำหรับฉันรูปแบบโดเมน Anemic แบ่งแนวคิดหลักของ OOP (ซึ่งผูกมัดคุณลักษณะและพฤติกรรม) แต่อาจหลีกเลี่ยงไม่ได้ขึ้นอยู่กับตัวเลือกสถาปัตยกรรม โดเมนแอนนิดีคิดง่ายกว่าน้อยกว่าและเรียงตามลำดับมากขึ้น

ระบบจำนวนมากมักจะทำเช่นนี้เมื่อหลายเลเยอร์ต้องเล่นด้วยข้อมูลเดียวกัน (บริการเลเยอร์เลเยอร์เว็บเลเยอร์ไคลเอนต์เอเจนต์ ... )

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

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

คุณสามารถทำให้ข้อมูล "วัตถุ" เป็นอนุกรมหรือลบบางส่วนหรือเป็นรูปแบบอื่น (json) ได้ง่ายเกินไปโดยไม่ต้องกังวลเกี่ยวกับแนวคิด / ความรับผิดชอบของวัตถุใด ๆ มันเป็นเพียงข้อมูลที่ผ่านแม้ว่า คุณสามารถทำการแมปข้อมูลระหว่างสองคลาส (พนักงาน, EmployeeVO, EmployeeStatistic ... ) แต่พนักงานหมายความว่าอย่างไรที่นี่จริง ๆ ?

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

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


ขอบคุณสำหรับการป้อนข้อมูลของคุณวินซ์ ประเด็นคือคุณไม่ต้องการเลเยอร์บริการเมื่อคุณมีโดเมนมากมาย มีเพียงคลาสเดียวที่รับผิดชอบต่อพฤติกรรมนี้และเป็นเอนทิตีโดเมนของคุณ เลเยอร์อื่น ๆ (เลเยอร์เว็บ UI ฯลฯ ... ) โดยทั่วไปแล้วจะจัดการกับ DTOs และ ViewModels และนี่ก็ใช้ได้ รูปแบบโดเมนคือการสร้างแบบจำลองโดเมนไม่ทำงาน UI หรือส่งข้อความผ่านอินเทอร์เน็ต ข้อความของคุณสะท้อนถึงความเข้าใจผิดที่พบบ่อยซึ่งมาจากข้อเท็จจริงที่ว่าผู้คนไม่รู้วิธีที่จะทำให้ OOP เข้ากับการออกแบบของพวกเขา และฉันคิดว่ามันน่าเศร้ามาก - สำหรับพวกเขา
tobiak777

ฉันไม่คิดว่าฉันมีความเข้าใจผิดเกี่ยวกับโดเมน OOP ที่หลากหลายฉันได้ออกแบบซอฟแวร์จำนวนมากด้วยวิธีนี้และมันเป็นความจริงที่ดีสำหรับการบำรุงรักษา / วิวัฒนาการ แต่ฉันขอโทษที่จะบอกคุณว่านี่ไม่ใช่กระสุนเงิน
Vince

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

0

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

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


0

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


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