a) ความแตกต่างระหว่างSRPและSoCคืออะไร? บางทีนั่นอาจจะSRPถูกนำไปใช้ในระดับชั้นในขณะที่SoCสามารถนำมาใช้ในระบบ , ระบบย่อย , โมดูล , ระดับหรือฟังก์ชั่นระดับ
b) ถ้าคำตอบต่อa)ใช่แล้วSoC จะใช้คำพ้องความหมายสำหรับSRPในระดับชั้นเรียนหรือไม่?
ขอขอบคุณ
a) ความแตกต่างระหว่างSRPและSoCคืออะไร? บางทีนั่นอาจจะSRPถูกนำไปใช้ในระดับชั้นในขณะที่SoCสามารถนำมาใช้ในระบบ , ระบบย่อย , โมดูล , ระดับหรือฟังก์ชั่นระดับ
b) ถ้าคำตอบต่อa)ใช่แล้วSoC จะใช้คำพ้องความหมายสำหรับSRPในระดับชั้นเรียนหรือไม่?
ขอขอบคุณ
คำตอบ:
หลักการความรับผิดชอบเดี่ยวเป็นเรื่องเกี่ยวกับรหัสของคุณที่ทำสิ่งเดียวเท่านั้นและคุณสามารถแยกฟังก์ชันการทำงานทั้งหมดในหลายชั้นเรียนซึ่งทั้งหมดมีไว้สำหรับทำสิ่งที่เฉพาะเจาะจง 1 ตัวอย่างคือคลาสเฉพาะสำหรับการตรวจสอบความถูกต้องทำตรรกะทางธุรกิจบางอย่างเพิ่มคุณค่าของแบบจำลองการดึงข้อมูลอัปเดตข้อมูลนำทาง ฯลฯ
การแยกข้อกังวลเป็นเรื่องเกี่ยวกับโค้ดของคุณที่ไม่ได้ถูกผนวกเข้ากับคลาส / ระบบอื่น ๆ อย่างแน่นหนา การใช้อินเทอร์เฟซในรหัสของคุณช่วยได้มากวิธีนี้คุณสามารถเชื่อมโยงคลาส / ระบบเข้ากับโค้ดของคุณได้ ข้อตกลงนี้คือการทดสอบโค้ดของคุณก็ง่ายขึ้นเช่นกัน มีกรอบ (IoC) มากมายที่สามารถช่วยให้คุณบรรลุเป้าหมายนี้ได้ แต่คุณสามารถนำสิ่งเหล่านี้มาใช้ด้วยตัวเอง
ตัวอย่างของ SoC บางอย่าง แต่ไม่มี SRP
public class Foo
{
private readonly IValidator _validator;
private readonly IDataRetriever _dataRetriever;
public Foo(IValidator validator, IDataRetriever dataRetriever)
{
_validator = validator;
_dataRetriever = dataRetriever;
}
public NavigationObject GetDataAndNavigateSomewhereIfValid()
{
var data = _dataRetriever.GetAllData();
if(_validator.IsAllDataValid(data))
{
object b = null;
foreach (var item in data.Items)
{
b = DoSomeFancyCalculations(item);
}
if(_validator.IsBusinessDataValid(b))
{
return ValidBusinessLogic();
}
}
return InvalidItems();
}
private object DoSomeFancyCalculations(object item)
{
return new object();
}
private NavigationObject ValidBusinessLogic()
{
return new NavigationObject();
}
private NavigationObject InvalidItems()
{
return new NavigationObject();
}
}
อย่างที่คุณเห็นรหัสนี้ไม่ได้อยู่คู่กับคลาสหรือระบบอื่น ๆ อย่างแน่นหนาเพราะมันใช้เพียงบางอินเตอร์เฟสเพื่อทำสิ่งต่าง ๆ นี่เป็นสิ่งที่ดีจากมุมมองของ SoC
คุณจะเห็นว่าคลาสนี้มีวิธีการส่วนตัว 3 วิธีซึ่งทำสิ่งที่น่าสนใจ จากมุมมองของ SRP วิธีการเหล่านั้นควรวางไว้ในบางคลาสของตนเอง 2 ของพวกเขาทำอะไรบางอย่างด้วยการนำทางซึ่งจะพอดีกับบางคลาส INavigation อีกอันหนึ่งทำการคำนวณแฟนซีในไอเท็มซึ่งอาจวางไว้ในคลาส IBusinessLogic
มีบางอย่างเช่นนี้คุณทั้งคู่มี SoC และ SRP อยู่:
public class Foo
{
private readonly IValidator _validator;
private readonly IDataRetriever _dataRetriever;
private readonly IBusinessLogic _businessLogic;
private readonly INavigation _navigation;
public Foo(IValidator validator, IDataRetriever dataRetriever, IBusinessLogic businessLogic, INavigation navigation)
{
_validator = validator;
_dataRetriever = dataRetriever;
_businessLogic = businessLogic;
_navigation = navigation;
}
public NavigationObject GetDataAndNavigateSomewhereIfValid()
{
var data = _dataRetriever.GetAllData();
if(_validator.IsAllDataValid(data))
{
object b = null;
foreach (var item in data.Items)
{
b = _businessLogic.DoSomeFancyCalculations(item);
}
if(_validator.IsBusinessDataValid(b))
{
return _navigation.ValidBusinessLogic();
}
}
return _navigation.InvalidItems();
}
}
แน่นอนคุณสามารถถกเถียงกันได้ว่าควรวางตรรกะทั้งหมดนี้ไว้ในGetDataAndNavigateSomewhereIfValid
วิธีการนี้หรือไม่ นี่คือสิ่งที่คุณควรตัดสินใจด้วยตัวเอง สำหรับฉันดูเหมือนว่าวิธีนี้กำลังทำสิ่งต่าง ๆ มากเกินไป
สำหรับ SRP จะใช้เฉพาะในระดับชั้นเรียนในหนังสือของเขา Robert C. Martin (เท่าที่ฉันรู้ว่าเขานิยมถ้าไม่ได้มากับแนวคิด):
ทำความสะอาดรหัสหน้า 138 : "หลักการความรับผิดชอบเดี่ยว (SRP) ระบุว่าคลาสหรือโมดูลควรมีเหตุผลเพียงหนึ่งเดียวเท่านั้นที่จะเปลี่ยนได้"
ในหลักการเปรียวรูปแบบและการปฏิบัติใน C # หน้า 116 : "[... ] และเชื่อมโยงการเชื่อมโยงกับกองกำลังที่ทำให้โมดูลหรือคลาสเปลี่ยนไป"
เน้นการขุด
ในAPPPเขาพูดถึงความยาวที่มากขึ้นเกี่ยวกับ SRP และมุ่งเน้นไปที่เกือบทั้งหมดในระดับชั้นเรียน ในขณะที่เขาดูเหมือนจะให้ความสำคัญกับระดับชั้นเรียนฉันรู้สึกว่าหลักการก็ถูกนำไปยังโมดูลและการสร้างระดับที่สูงขึ้นอื่น ๆ
ด้วยเหตุผลดังกล่าวฉันจะไม่ผ่านการรับรอง SRP เป็น SoC ในระดับชั้นเรียนตามที่คุณแนะนำในคำถามของคุณ
ที่นี่คุณจะพบวิดีโอสั้น ๆ ที่อธิบายความแตกต่างระหว่างคำศัพท์เหล่านั้นอย่างชัดเจน https://www.youtube.com/watch?v=C7hkrV1oaSY
การแยกข้อกังวล (SoC) แบ่งแอปพลิเคชันของคุณออกเป็นคุณสมบัติที่แตกต่างโดยมีการเหลื่อมกันเล็กน้อยในการทำงานเท่าที่จะทำได้ (Microsoft)
“ กังวล” =“ คุณสมบัติที่แตกต่าง” =“ ส่วนที่แตกต่าง”
“ ความกังวล” ทำงานได้ทั้งในระดับสูงและระดับต่ำ
หลักการความรับผิดชอบเดี่ยวระบุว่าทุกโมดูลหรือคลาสควรมีความรับผิดชอบในส่วนของฟังก์ชั่นที่จัดทำโดยซอฟต์แวร์และความรับผิดชอบนั้นควรถูกห่อหุ้มทั้งหมดโดยชั้นเรียน บริการทั้งหมดของ บริษัท ควรสอดคล้องกับความรับผิดชอบนั้น (นิยามของ Wikipedia)
“ ความรับผิดชอบ” =“ เหตุผลในการเปลี่ยนแปลง”
เปลี่ยนอะไร “ ส่วนหนึ่งของฟังก์ชั่นที่จัดทำโดยซอฟต์แวร์” = หน่วยพื้นฐาน
ข้อสรุป
ความรับผิดชอบเดี่ยวหลักการทำงานในหน่วยพื้นฐาน -> ทำงานในระดับต่ำ
การแยกข้อกังวลทำงานได้ทั้งในระดับสูงและระดับต่ำ
SRP และ SoC ทำงานร่วมกันเพื่อแยกข้อกังวล พวกเขาเหมือนกันในระดับต่ำ
นี่คือความเข้าใจของฉันเกี่ยวกับหลักการเหล่านี้
การแยกข้อกังวล (SoC) - เป็นเรื่องเกี่ยวกับการแบ่งระบบซอฟต์แวร์ออกเป็นโมดูลที่เล็กลงแต่ละส่วนในโมดูลเหล่านี้มีหน้าที่รับผิดชอบข้อกังวลเดียว ข้อกังวลในกรณีนี้คือคุณสมบัติหรือกรณีการใช้งานของระบบซอฟต์แวร์ โมดูลมี API (อินเตอร์เฟส) ที่กำหนดไว้อย่างดีซึ่งทำให้ทั้งระบบมีความยืดหยุ่นสูง มีสองประเภทหลักคือแนวนอนและแนวตั้ง
Single Responsibility Principle (SRP) - เป็นหลักการออกแบบที่ระบุว่าแต่ละ Building Block (อาจเป็นคลาส, โมดูล, วัตถุหรือแม้กระทั่งฟังก์ชั่น) ของระบบควรมีเพียงความรับผิดชอบเดียว โรเบิร์ตซี. มาร์ติน มาร์ตินอธิบายความรับผิดชอบเป็นเหตุผลในการเปลี่ยนแปลง โดยทั่วไปแล้วจะดีกว่ามากถ้ามีคลาส / วัตถุเดียวที่มีความรับผิดชอบในส่วนหนึ่งของการทำงานแทนที่จะสามารถทำหน้าที่ได้มากบางครั้งก็ไม่เกี่ยวข้องกับฟังก์ชั่นทำให้คลาสนี้มีขนาดใหญ่และแน่นหนาดังนั้น - เรียกว่า "พระเจ้าวัตถุ"
นอกจากนี้ฉันอธิบายหลักการเหล่านี้โดยละเอียดยิ่งขึ้นในโพสต์บล็อกของฉันโปรดดู
https://crosp.net/blog/software-architecture/srp-soc-android-settings-example/