ออกแบบเพื่อการเปลี่ยนแปลงในอนาคตหรือแก้ปัญหาได้ในมือ [ปิด]


37

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

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

ฉันเดาทางออกคือการหาทางสายกลางที่พูดง่ายกว่าทำ คุณจัดการปัญหาประเภทนี้อย่างไร หากคุณเริ่มพูดคุยเรื่องทั่วไปในช่วงเวลาใดที่คุณรู้ว่าการสรุปทั่วไปนี้เพียงพอหรือไม่



นี่เป็นคำถามที่สำคัญมาก: คุณสามารถคาดการณ์ได้ว่าความต้องการจะเปลี่ยนแปลงไปอย่างไร
user16764

ผู้คนมากมายจะบอกคุณว่า YAGNI เหล่านี้คือคนที่คุณดูถูกเมื่อคุณต้องทำงานของพวกเขา
Martin Maat

คำตอบ:


60

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

หากต้องการต้มให้เหลือเพียงกฎเดียว: น้อยกว่ามาก


17
+1 "อนาคตไม่ใช่สิ่งที่เคยเป็น"
Dan Lyons

19

คุณคุ้นเคยกับเปรียวไหม? หนึ่งในหลักการใหญ่ของเปรียวเป็นYAGNI ฉันพบว่าเป็นวิธีที่ดีที่สุดในการเข้าถึงสิ่งต่าง ๆ

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

... YAGNI เป็นหลักการเบื้องหลังการฝึกฝน XP ของ "ทำสิ่งที่ง่ายที่สุดที่อาจเป็นไปได้" (DTSTTCPW) มันมีความหมายที่จะใช้ในการรวมกันกับการปฏิบัติอื่น ๆ หลายประการเช่นการอย่างต่อเนื่องrefactoringต่อเนื่องอัตโนมัติทดสอบหน่วยและบูรณาการอย่างต่อเนื่อง ใช้โดยไม่มีการปรับโครงสร้างอย่างต่อเนื่องอาจทำให้รหัสยุ่งและทำซ้ำขนาดใหญ่ การปรับโครงสร้างอย่างต่อเนื่องนั้นอาศัยการทดสอบหน่วยอัตโนมัติเป็นเครือข่ายความปลอดภัย (เพื่อตรวจจับข้อบกพร่องที่ไม่คาดคิด) และการรวมอย่างต่อเนื่องเพื่อป้องกันปัญหาการรวมที่กว้างขึ้น ...

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


3
ในขณะที่ผมเห็นด้วยกับ YAGNI มากกว่าหรือน้อยกว่าฉันไม่สามารถหาได้ในหลักการเปรียว: agilemanifesto.org/principles.html
Jens Schauder

"ความเรียบง่าย - ศิลปะของการเพิ่มปริมาณงานที่ไม่ได้ทำ - เป็นสิ่งจำเป็น" จะนำไปใช้กับ YAGNI และแนวทางปฏิบัติที่คล่องตัวอื่น ๆ
tvanfosson

1
แม้ว่ามันจะไม่ได้พูดว่า "YAGNI" โดยเฉพาะในแถลงการณ์ แต่ฉันคิดว่าพวกเขาสอดคล้องกันมาก

2
@Jens และ @Matt, YAGNI อยู่ใน Agile โดยใช้ XP ที่รวมเป็นวิธีการ "เปรียว" ดังที่ได้กล่าวไว้ในบทความ Wikipedia หลักการ YAGNI ได้รับการพัฒนาโดย Ron Jeffries ซึ่งเป็นส่วนหนึ่งของหลักปฏิบัติ XP

1
มันอาจเป็นจริงที่ YAGNI เป็นสำนวนของนักพัฒนา แต่ TDD เป็นสิ่งที่ใช้ความไม่แน่นอนนี้เป็นอย่างดี ในขั้นตอนที่แจ้งว่าคุณควรเขียนรหัสเพียงพอที่จะผ่านการทดสอบและไม่มาก และ TDD เป็นส่วนหนึ่งของความคล่องตัว
Robert Koritnik

12

นี่อาจเป็นหนึ่งในส่วนที่ยากที่สุดของการพัฒนาซอฟต์แวร์เพราะคุณต้องเดินตามเส้นแบ่งระหว่าง "YAGNI" และ "PYIAC" (เพ้นท์ตัวเองให้เข้ามุม)

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

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


7

ฉันใช้เวลาคิดล่วงหน้าเกี่ยวกับทิศทางทั่วไปของการออกแบบ - ไม่มากเกินไป แต่พอที่จะสรุปภาพรวมระดับสูงได้ จากนั้นฉันทำตามวิธีการแบบเปรียวโดยใช้ TDD เพื่อพัฒนาโซลูชันสำหรับแต่ละเรื่อง ในขณะที่ฉันกำลังใช้งานผ่าน TDD ฉันคำนึงถึงภาพรวมระดับสูงของฉันและ (a) นำการใช้งานเฉพาะของฉันไปตามภาพรวมระดับสูงหรือ (b) refactor (และปรับปรุง) ความเข้าใจ / ทิศทางระดับสูงของฉันตาม สิ่งที่ฉันเรียนรู้ระหว่างการทดสอบ / การนำไปใช้งาน

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


3

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


2

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

ฉันคิดว่าฉันเคยได้ยินคนอื่นพูดอะไรบางอย่างกับผลของ:

ฉันแก้ปัญหาครั้งแรก เมื่อฉันทำซ้ำโซลูชันของฉันในครั้งแรกฉันบันทึกมัน เมื่อฉันทำซ้ำอีกครั้งฉัน refactor


2

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

สิ่งนี้ขึ้นอยู่กับโครงการและในระยะสั้นประสบการณ์จะสอนคุณว่า "+1" คืออะไร


1

ปรัชญาของYAGNIคุณไม่ต้องการมันสามารถสรุปได้ด้วย (จากบทความ):

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

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

0

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

โดยพื้นฐานแล้วจะมีรายการข้อกำหนดเฉพาะออกแบบกับสิ่งนั้นไม่ได้หมายความว่าคุณไม่ควร:

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

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

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

พูดอย่างนั้นเหรอ? "เมื่อสิ่งที่คุณมีคือค้อนทุกสิ่งจะเริ่มดูเหมือนเล็บ"

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

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