Dijkstra ตั้งใจที่จะทำโค้ดให้เป็นมาตรฐานหรือไม่เมื่อเขาเขียนเกี่ยวกับการแยกข้อกังวล?


9

ก่อนอื่นฉันอ่านข้อความที่ตัดตอนมาของ Edsger W. Dijkstra ในปี 1974 "ในบทบาทของความคิดทางวิทยาศาสตร์":

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

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

กล่าวคือมีโค้ดอยู่ข้างหน้าคุณว่าในไฟล์เดียวมีแนวคิดของมุมมองพื้นที่เก็บข้อมูลตัวควบคุมการจัดการเหตุการณ์โรงงาน ฯลฯ ทั้งหมดในไฟล์เดียว

สำหรับตัวอย่างสั้น ๆ นี่คือโค้ดบางส่วนที่มีการเข้าถึงข้อมูลและมุมมอง (เอาต์พุต):

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

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

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

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

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

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


5
ฉันค่อนข้างแน่ใจว่าในปี 1974 เขาเพิ่งเห็นการเขียนโปรแกรมแบบแยกส่วนที่เห็นได้ชัดและนั่นเป็นสาเหตุที่เขาไม่ได้พูดคุยเรื่องนี้อย่างชัดเจนในบทความนั้น กระดาษ Parnas เกี่ยวกับวิธีการที่จะ modularize เป็นในปี 1972 และในเวลานั้นไม่ว่าจะ modularize อยู่แล้วไม่มีคำถาม ในความเป็นจริงสิ่งที่คุณอธิบายไม่ได้เป็นเพียงการเขียนโปรแกรมแบบแยกส่วน แต่มันคือการเขียนโปรแกรมที่มีโครงสร้างซึ่ง Dijkstra เองก็เถียงกันอย่างมากในปี 1968 ในบทความ "Go To Considered Harmful" ที่คลาสสิคของเขา
Jörg W Mittag

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

@ JörgWMittagคุณสามารถกำหนดความแตกต่างระหว่างการเขียนโปรแกรมแบบโครงสร้างและแบบแยกส่วนได้หรือไม่? ลิงก์บางรายการใน google แนะนำว่าเหมือนกัน
Dennis

โครงสร้าง = IF, WHILE, แทนFOR GOTOModular = modules ที่มี API สาธารณะที่กำหนดชัดเจนแยกจากการใช้และการนำเสนอภายในที่ซ่อนอยู่อย่างเคร่งครัด (เช่น Modula, Mesa, Modula-2, Modula-3, ภาษา Pascal ต่อมา ( UNIT))
Jörg W Mittag

คำตอบ:


2

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


14

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

Modularisation (การแยกกลุ่มของฟังก์ชั่นที่ไม่เกี่ยวข้องออกเป็นโมดูล), การห่อหุ้ม (ซ่อนรายละเอียดภายในของโมดูล) และนามธรรม (การแยกทั่วไปจากที่เฉพาะเจาะจงและความคิดจากการใช้งาน) ล้วนหมายถึงการใช้วิธีนี้ในโดเมน ของการออกแบบซอฟต์แวร์


9

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

มีหลักฐานมากมายที่แสดงว่าการปรับเป็นประโยชน์อย่างมหาศาลและประโยชน์เหล่านั้นมีมากกว่า "ภาระ" ที่เกิดขึ้นกับเรา ไม่ว่า Dijkstra จะหมายถึงอะไรในตอนนั้นอย่าเปลี่ยนความจริงที่ว่าโค้ดเล็ก ๆ แต่ละอันเน้นไปที่สิ่งเดียวนำไปสู่โค้ดที่ง่ายต่อการเขียนอ่านเข้าใจรักษาและทดสอบ


5
ฉันคิดว่ามันควรจะสังเกตว่าความคิดสมัยใหม่เกี่ยวกับการแยกความกังวลส่วนใหญ่มาจากเอกสารตอนแรก ๆ ซึ่งในที่สุดก็วางไข่ Aspect Oriented Programming จาก IBM ฉันคิดว่าเอกสารเริ่มต้น (ปลาย 90s- ต้น 2000s) มีอิทธิพลมากที่สุดที่นั่น ไม่นานมานี้และเว็บไซต์ต่างก็เปลี่ยนแปลงไป ไม่แน่ใจว่าฉันจะสามารถหาพวกเขาได้อีกครั้งหรือไม่
Berin Loritsch

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

1
มันจะช่วยให้เราเข้าใจตำแหน่งของคุณอย่างแท้จริงหากคุณจะ (ก) อธิบายสิ่งที่คุณคิดว่า Dijkstra แปลโดย "แยกความกังวล" และ (b) อธิบายว่าทำไมคุณถึงคิดว่าสิ่งที่เขาหมายถึงไม่มีความเกี่ยวข้องอีกต่อไป
John R. Strohm

2

ฉันสามารถยกตัวอย่างส่วนตัวของคุณเกี่ยวกับการแยกข้อกังวลที่ฉันคิดว่าเปรียบได้กับแนวคิดของ Dijkstra เมื่อฉันวิเคราะห์หัวข้อเฉพาะในซอฟต์แวร์ฉันสร้างสามมุมมอง

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

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

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


1

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

  • แบบพกพา
  • เข้าถึงได้จากเครื่องมือภายนอกที่แตกต่างกันมากมาย
  • เข้าถึงได้โดยโปรแกรมเมอร์หลายคน
  • รุ่นและเทียบเท่า
  • ปรับขนาดได้ดีกับระบบปฏิบัติการที่ดีในการจัดการไฟล์

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

นี่ไม่ใช่เชื้อราหรือสาหร่ายที่เจริญเติบโตแม้ว่า ... เป็นอย่างไรสำหรับความจริงที่ต่ำต้อย?


-1

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

ควรปฏิบัติตามหลักการของ SOLID ในการพัฒนาโดยใช้ OO นี่คือลิงค์ที่ดีสำหรับพวกเขา แต่ TLDR สำหรับ "การแยกข้อกังวล" ส่วนใหญ่อยู่ใน S ใน SOLID: หลักการความรับผิดชอบเดี่ยวหรือ SRP

แน่นอนที่สุดนี่คือการออกกำลังกายไม่ใช่จิต ตัวอย่างเช่นคุณโดยเฉพาะ MVC (หรือพี่น้องของมัน MVVM และ MVP) นำหนึ่งไปยังร่างกายแยกคอนเสิร์ตของ Model, View, และ Controller / Presenter / ViewModel เป็นไฟล์แยกต่างหาก ฉันเคยเห็นการใช้งาน MVVM บางส่วนซึ่งสิ่งเหล่านี้ถูกนำไปใช้ในการประกอบที่แยกต่างหากเพื่อ จำกัด แนวโน้มที่จะ "รวมแนวคิด"

แต่. มันเป็นมากกว่าแค่เรื่องง่าย "นี่คือมุมมองและนี่คือแบบจำลอง" ถ้าคุณทำตามมุมมองของลุงบ็อบเกี่ยวกับเรื่องนี้

ต้องพิจารณาแหล่งที่มาของข้อกำหนดสำหรับองค์ประกอบ OO เฉพาะ หากคุณกำลังผสมพูดสิ่งที่ลูกค้าต้องการกับสิ่งที่พนักงานปฏิบัติการต้องการคุณยังละเมิด SRP หรือเพื่อให้เป็นเหมือนลุงบ๊อบ: คลาสควรมีเหตุผลเดียวเท่านั้นที่จะเปลี่ยน

ฉันขอแนะนำให้คุณศึกษาเพิ่มเติมโดยใช้ลิงก์ที่ให้มาหรือทำการค้นหาเว็บสำหรับ "หลักการที่มั่นคง"


ไม่ได้หลักการของ SOLID นั้นถูกตัดการเชื่อมต่อจากความเป็นจริงของการเขียนรหัส (= ปรัชญา) ที่พวกเขาสามารถเข้าใจได้ในวิธีที่มีประโยชน์จากระยะไกลเมื่อคุณรู้วิธีการเขียนโค้ดที่ดี ใช้พวกเขาเป็นหลักการชี้นำโดยไม่ต้องมีประสบการณ์และความสามารถในการผลิตรหัสที่ดีมาก
jpmc26
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.