การจัดการกับการแยกคุณลักษณะ


11

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

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

มิติของปัญหาการแยกคุณลักษณะนี้มีความซับซ้อนที่เหลือเชื่อ สมมติว่าเวอร์ชันซอฟต์แวร์ปัจจุบันมีNคุณสมบัติและคุณเพิ่มคุณสมบัติใหม่หนึ่งรายการ นอกจากนี้เราจะทำให้สิ่งต่าง ๆ ง่ายขึ้นด้วยการบอกว่าคุณลักษณะแต่ละอย่างสามารถเปิดหรือปิดได้เท่านั้นจากนั้นคุณ2^(N+1)มีการผสมผสานคุณสมบัติที่เป็นไปได้ที่จะต้องพิจารณา เนื่องจากการขาดการใช้ถ้อยคำที่ดีกว่า / คำค้นหา, ผมหมายถึงการดำรงอยู่ของชุดเหล่านี้เป็นปัญหาคุณลักษณะที่สี่แยก (คะแนนโบนัสสำหรับคำตอบรวมถึงการอ้างอิงสำหรับคำที่กำหนดขึ้น)

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

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

  • ข้อมูลจำเพาะ: เมื่อคุณระบุคุณลักษณะใหม่ - คุณจะมั่นใจได้อย่างไรว่ามันเล่นได้ดีกับเด็กคนอื่น ๆ ทั้งหมด?

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

  • การติดตั้งใช้งาน: เมื่อคุณติดตั้งฟีเจอร์ - คุณจะมั่นใจได้อย่างไรว่าโค้ดของคุณโต้ตอบ / ตัดกันอย่างถูกต้องในทุกกรณี

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

  • การตรวจสอบ: เมื่อคุณทดสอบคุณสมบัติ - คุณจัดการกับความจริงได้อย่างไรว่าคุณสามารถทดสอบเพียงเสี้ยวหนึ่งของพื้นที่จุดตัดคุณลักษณะนี้ได้อย่างไร

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

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


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

คำตอบ:


6

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

ในทางปฏิบัติการออกแบบที่ดีสามารถให้ decoupling เช่นจำนวนคุณลักษณะการตัดกันน้อยกว่า 2 ^ N ถึงแม้ว่ามันจะดูเหมือนว่าจะเหนือ N แม้ในระบบที่ออกแบบมาอย่างดี

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

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

หรืออาจจะไม่ ฉันไม่รู้อะไรเกี่ยวกับ RavenDB สถาปัตยกรรมไม่สามารถป้องกันปัญหาการตัดกันของฟีเจอร์หากฟีเจอร์นั้นมีการผสมผสานอย่างลึกลับและเราไม่สามารถรู้ล่วงหน้าได้ว่าเราไม่ต้องการฟีเจอร์ที่มีกรณีที่เลวร้ายที่สุดของการแยก 2 ^ N แต่อย่างน้อยสถาปัตยกรรมสามารถ จำกัด จุดตัดได้เนื่องจากปัญหาการใช้งาน

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

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

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


0

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

การสนับสนุนโครงสร้าง

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

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

สิ่งนี้ค่อนข้างสำคัญเมื่อเพิ่มการสนับสนุนสำหรับ X หลายตัวที่เกี่ยวข้องกับโค้ดแบบเกลียว / แบบอะซิงโครนัส / การขับเคลื่อนโดยเหตุการณ์เพราะสิ่งต่าง ๆ อาจแย่ลงอย่างรวดเร็ว

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

ออกแบบ

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

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

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

ลดความซับซ้อน!

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

อย่างไรก็ตามนั่นคือ 2c ของฉัน

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