จะดีกว่าที่จะออกแบบจากบนลงล่างหรือล่างขึ้นบน?


31

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

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

กระบวนการของ:

  • การสร้างสเป็คความต้องการ
  • สร้างข้อกำหนดการออกแบบ (พร้อมไดอะแกรม)
  • Implement
  • ส่งมอบ
  • ทำซ้ำ (ในการพัฒนาซ้ำ ๆ แทนที่จะทำทั้งก้อนในแต่ละขั้นตอนเราทำกันเล็กน้อยซ้ำแล้วซ้ำอีกและมีการประชุมประจำวันเพื่อปรับให้เข้ากับความต้องการแบบไดนามิกของลูกค้า)

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

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

ในการเขียนโปรแกรมเรียงความของเขาBottom Upดูเหมือนว่า Paul Graham จะสนับสนุนการสร้างจากล่างขึ้นบนอย่างสมบูรณ์หรือตั้งโปรแกรมจากล่างขึ้นบน แต่ไม่ใช่ช่วงการวิเคราะห์ความต้องการ / การออกแบบ:

โปรแกรมเมอร์ Lisp ที่มีประสบการณ์แบ่งโปรแกรมต่างกันออกไป เช่นเดียวกับการออกแบบจากบนลงล่างพวกเขาปฏิบัติตามหลักการที่เรียกว่าการออกแบบจากล่างขึ้นบน - เปลี่ยนภาษาเพื่อให้เหมาะกับปัญหา

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

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

สิ่งนี้หมายความว่าในช่วงเวลาที่เขียนโปรแกรมใน Lisp คุณต้องใช้เครื่องมือทั่วไปหรือไม่?


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

@ S.Robins สรุปแล้วฉันได้สาธิตวิธีการจากบนลงล่างเพื่อพัฒนาซอฟต์แวร์ อย่างไรก็ตามบางคนชอบล่างขึ้นบนและหนึ่งในนั้นคือ Paul Graham ซึ่งเป็นบุคคลที่มีชื่อเสียง ฉันขอให้เข้าใจว่าการออกแบบจากล่างขึ้นบนช่วยโดยทั่วไปอย่างไรและโดยเฉพาะใน LISP เนื่องจากมีคุณสมบัติพิเศษที่จะส่งเสริม
Amumu

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

คำตอบ:


35

จากบนลงล่างเป็นวิธีที่ยอดเยี่ยมในการอธิบายสิ่งที่คุณรู้หรือเพื่อสร้างสิ่งที่คุณได้สร้างขึ้นใหม่

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

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

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

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

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

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

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

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

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

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

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

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

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

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

มีการพัฒนาระบบซอฟต์แวร์ที่ซับซ้อนขึ้นใหม่ไม่ใช่การออกแบบ ทุกครั้งที่มีคนเริ่มออกแบบระบบซอฟต์แวร์ที่ซับซ้อนที่ไม่ระบุตัวใหม่ขนาดใหญ่ตั้งแต่เริ่มต้น (โปรดทราบว่าโครงการซอฟต์แวร์ขนาดใหญ่ที่ซับซ้อนมีความเป็นไปได้เพียงสามประการเท่านั้น: a] ข้อมูลจำเพาะนั้นคลุมเครือ หรือ c] ทั้ง ... และบ่อยครั้งที่ [c] เป็นกรณี)

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

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

ความคิด Lisp หลายอย่างกำลังได้รับความนิยมมากขึ้น (ฟังก์ชั่นชั้นหนึ่ง, การปิด, การพิมพ์แบบไดนามิกเป็นค่าเริ่มต้น, การเก็บขยะ, metaprogramming, การพัฒนาเชิงโต้ตอบ) แต่ Lisp ยังคงเป็นทุกวันนี้ สำหรับสิ่งที่คุณต้องการ

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

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

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


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

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

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

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

1
สวัสดี Mr.6502 หลังจากผ่านไปหนึ่งปีเมื่อฉันเรียนรู้สิ่งต่าง ๆ มากขึ้นฉันเริ่มเห็นสิ่งที่คุณพูดว่าเป็นเรื่องจริง ฉันทำด้ายอื่น: programmers.stackexchange.com/questions/179000/... หากคุณมีเวลาฉันหวังว่าคุณจะชี้แจงความคิดของฉันอีกครั้ง: D
Amumu

6

ฉันไม่แน่ใจว่าคำตอบนี้จะนำไปใช้กับ Lisp ได้อย่างไร แต่ฉันเพิ่งอ่านAgile Principles, รูปแบบและการปฏิบัติและผู้เขียนUncle Bobได้แนะนำให้ใช้วิธีการจากบนลงล่างสำหรับ C # (เช่น C ++) ด้วย ตกลง.

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

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

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

หากคุณสนใจที่จะอ่านเพิ่มเติมเกี่ยวกับ XP และการออกแบบเชิงวิวัฒนาการนี่คือการอ่านที่ดีจาก Martin Fowler ผู้เขียนที่ยอดเยี่ยมคนอื่น: "Is Design Dead?"


สมบูรณ์ นี่คือสิ่งที่ฉันพูดถึง นอกจากนี้ยังเป็นเรื่องดีที่ได้รู้เกี่ยวกับหลักการของ SOLID และ Agile รองรับวิธีการจากบนลงล่าง (ฉันคิดว่าด้วย TDD และ XP ผู้คนจะข้ามไปที่โค้ดโดยเร็วและหลีกเลี่ยงเอกสารประกอบ)
Amumu

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

3

สำหรับฉันคำพูดที่สำคัญที่สุดที่ Paul Graham กล่าวไว้ในบทความของเขาคือ:

[... ] Lisp โปรแกรมเมอร์ [... ] ทำตามหลักการที่เรียกว่าการออกแบบจากล่างขึ้นบน - เปลี่ยนภาษาเพื่อให้เหมาะกับปัญหา ใน Lisp คุณไม่เพียง แต่เขียนโปรแกรมของคุณลงไปในภาษาคุณยังสร้างภาษาขึ้นไปยังโปรแกรมของคุณ

หรือตามที่รู้จักกันในแวดวง C ++: การออกแบบห้องสมุดคือการออกแบบภาษา (Bjarne Stroustrup)

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

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


2

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

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

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

โปรดทราบว่าไม่เหมือนกับรถยนต์จริงและล้อจริงหากคุณสร้างซอฟต์แวร์ "ล้อ" หนึ่งตัวคุณได้สร้างจำนวนไม่ จำกัด

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

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

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


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

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

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

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

ลองมาตัวอย่าง: สมมติว่าเรากำลังเขียนโปรแกรมไคลเอนต์ / เซิร์ฟเวอร์ สิ่งแรกที่เราต้องระบุโปรโตคอลโดยการกำหนดข้อความแลกเปลี่ยนวิธีการที่ข้อความถูกวางในหน่วยความจำ (เช่นส่วนหัว 16 ไบต์, id 4 ไบต์ .... ) แผนภาพไม่เท่ากับการสร้างแบบจำลอง / การวางแผน: abstratt.com/blog/2009/05/03/on-code-being-model เราไม่จำเป็นต้องใช้ UML หรือไดอะแกรมเป็นโมเดลเนื่องจาก UML จะเน้นเฉพาะ OOP และเวลาที่ใช้ในการพิมพ์ในแผนภาพคลาส UML นั้นไม่น้อยไปกว่าการพิมพ์รหัสจริงถ้าไม่มาก
Amumu

1

เกิดอะไรขึ้นกับวิธีการจากบนลงล่างร่วมกับการพัฒนาแบบวนซ้ำ

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

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

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

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

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

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


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