สิ่งที่เป็นนามธรรมมากเกินไปอาจไม่ดีหรือไม่?


46

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

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

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

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

หมายเหตุ: นี่ไม่เกี่ยวกับการอ่านรหัส! ทั้งโค้ดที่ 1 และ 2 สามารถอ่านได้ แต่โค้ดที่ 2 มาพร้อมกับ abstractions ที่ซับซ้อนมากขึ้นในขณะที่ code 1 มาพร้อมกับ abstractions แบบง่าย


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

25
“ มากเกินไป” ไม่ดีตามคำจำกัดความ
Jon Purdy

@JimmyHoffa: ต้องรักษาพวกมันไว้ในที่ของพวกมัน และอย่าอิจฉา - ฉันไม่ได้เขียน Haskell ตลอดทั้งวัน ส่วนใหญ่เป็น PHP, JavaScript, และ OCaml
Jon Purdy

คำตอบ:


78

คำแรกของ TC ++ PL4:

ปัญหาทั้งหมดในวิทยาการคอมพิวเตอร์สามารถแก้ไขได้โดยการอ้อมอีกระดับหนึ่งยกเว้นปัญหาของการอ้อมมากเกินไป - เดวิดเจวีลเลอร์

(David Wheeler เป็นที่ปรึกษาวิทยานิพนธ์ของฉันบางครั้งคำพูดที่ไม่มีบรรทัดสุดท้ายที่สำคัญบางครั้งเรียกว่า "กฎข้อแรกของวิทยาศาสตร์คอมพิวเตอร์")


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

2
@ m3th0dman - คุณมีระดับที่เหมาะสมของนามธรรมเมื่อมันง่ายที่จะทำการเปลี่ยนแปลงในอนาคต แน่นอนคุณสามารถถามว่าคุณรู้ได้อย่างไรว่าเมื่อใดจะเกิดขึ้นซึ่งเพียงแค่วนคำถามซ้ำในลักษณะที่แตกต่างกัน


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

1
ให้อภัยความไม่รู้ของฉัน แต่ฉันไม่เข้าใจ "TC ++ PL4"
LastTribunal

30

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

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


1
"และนั่นหมายความว่าในบางจุดสิ่งที่เป็นนามธรรมจะรั่วไหลในทางใดทางหนึ่ง": จริง สิ่งที่เป็นนามธรรมที่ดีกว่าคือการรั่วไหลที่น้อยลง
Giorgio

11
ในแง่ของคำตอบของ Bjarne (และหน้าอ้างอิงของวิกิพีเดียของ David Wheeler ) คุณอาจเปลี่ยนลักษณะการอ้างอิงของคุณได้ไหม? :)
congusbongus

2
@CongXu: Btw ฉันได้ไปจากที่อื่น: googling สำหรับ "คำพูด Bjarne Stroustrup" และยังไม่พบการอ้างอิงเดียวของ Bjarne ที่มีการพูดวลี "เพิ่มอีกชั้นหนึ่งของทางอ้อม" ... ไม่แน่นอน ทำให้มันไม่น่าเป็นไปได้สูงที่เขาจะเป็นคนแรกที่พูดออกมา
Marjan Venema

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

2
ฉันเคยได้รับคำแนะนำจากผู้อาวุโสอย่างไร้เดียงสาเพื่อเพิ่มสิ่งที่เป็นนามธรรมซึ่งไม่จำเป็น มันไม่เคยถูกใช้เกินกว่าที่ฉันต้องการจะทำในตอนแรก
Cees Timmerman

15

ใช่อย่างแน่นอน

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

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

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

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

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

กลับไปที่หัวข้อ

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

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

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

ในที่สุดโค้ดที่ซับซ้อนจะมีความซับซ้อน มักจะไม่มีทางแก้ไข แต่รหัสที่มีการพึ่งพาน้อยกว่านั้นง่ายกว่าที่จะเข้าใจได้ง่ายกว่ารหัสที่อาศัยสถานะภายนอกต่างๆ


2
+1 สำหรับ "ช่างตัดเสื้อที่ดีอย่าทิ้งผ้าไว้ที่ตะเข็บแต่ละอันเพราะคุณเกิดแขนที่สามขึ้นหรือตั้งครรภ์" เรามักจะออกแบบซอฟต์แวร์ด้วยวิธีนี้น่าเศร้า
Kemoda

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

13

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

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

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