ทีมของฉันจะหลีกเลี่ยงข้อผิดพลาดบ่อยครั้งได้อย่างไรหลังจากทำการเปลี่ยนใหม่


20

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

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

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

จะกำจัดปัญหาเหล่านั้นได้อย่างไร? 'เทคนิคการประกาศ' แบบไหนที่คุณสามารถแนะนำฉันได้บ้าง


34
คำตอบที่ชัดเจนคือTDD
mouviciel

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

4
@mouvciel นั่นและไม่ใช้การพิมพ์แบบไดนามิกแต่คำแนะนำเฉพาะนั้นมาช้าไปหน่อยในกรณีนี้
Doval

3
ใช้ภาษาที่พิมพ์อย่างยิ่งเช่น OCaml
ออกุสตุส

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

คำตอบ:


24

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

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

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


ฉันได้อ่านใน "The Mythical Man-Month" ซึ่งโครงสร้างรหัสมักตามหลังโครงสร้างทีม / องค์กร ดังนั้นนี่ไม่ใช่ "การปฏิบัติที่ไม่ดี" แต่เป็นวิธีที่สิ่งต่าง ๆ มักจะไป
Marcel

ฉันคิดว่าใน " Dynamics ของการพัฒนาซอฟต์แวร์ " ผู้จัดการที่อยู่เบื้องหลัง Visual C ++ แนะนำให้มีทีมงานคุณลักษณะอย่างชัดเจน ฉันยังไม่ได้อ่าน "The Mythical Man-Month", @Marcel แต่ AFAIK แสดงการปฏิบัติที่ไม่ดีในอุตสาหกรรม ...
logc

Marcel มันเป็นความจริงว่านี่เป็นวิธีที่สิ่งต่าง ๆ มักจะไปหรือไป แต่ทีมต่าง ๆ กำลังทำมันแตกต่างกันมากขึ้นเช่นทีมงานฟีเจอร์ การมีทีมงานตามส่วนประกอบส่งผลให้ขาดการสื่อสารเมื่อทำงานกับคุณสมบัติองค์ประกอบข้าม ถัดจากนั้นจะส่งผลให้การอภิปรายทางสถาปัตยกรรมไม่ได้ขึ้นอยู่กับวัตถุประสงค์ของสถาปัตยกรรมที่ดี แต่ผู้คนพยายามผลักดันความรับผิดชอบไปยังทีม / ส่วนประกอบอื่น ๆ ดังนั้นคุณจะได้รับสถานการณ์ที่อธิบายโดยผู้เขียนคำถามนี้ ดูเพิ่มเติมmountaingoatsoftware.com/blog/the-benefits-of-feature-teams
Tohnmeister

เท่าที่ฉันเข้าใจ OP เขาระบุว่าทีมจะไม่แยกออกเป็นทีมหลักและทีมที่ไม่ใช่แกน ทีมมีการแยก "ต่อลูกค้า" ซึ่งก็คือ "ต่อโดเมนการทำงาน" และนั่นเป็นส่วนหนึ่งของปัญหา: เนื่องจากทุกทีมได้รับอนุญาตให้เปลี่ยนแกนกลางร่วมกันการเปลี่ยนแปลงจากทีมหนึ่งจึงส่งผลกระทบต่ออีกทีม
Doc Brown

@DocBrown คุณพูดถูก แต่ละทีมอาจเปลี่ยนแกน แน่นอนการเปลี่ยนแปลงเหล่านั้นควรจะเป็นประโยชน์สำหรับแต่ละโครงการ อย่างไรก็ตามมันทำงานกับแบ็คล็อกที่แตกต่างกัน เรามีหนึ่งสำหรับลูกค้าแต่ละรายและหนึ่งสำหรับแกน
SDD64

41

เราเป็นส่วนที่แย่ที่สุดของแกนกลางซึ่งยังไม่ได้ทดสอบ

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


10
สิ่งนั้นและการปรับโครงสร้างในขั้นตอนทารก
Stefan Billiet

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

ฉันให้ "+1" กับคุณ แต่ฉันคิดว่า "การทดสอบอัตโนมัติ" ไม่ใช่วิธีเดียวที่จะแก้ปัญหานี้ คู่มือที่ดีขึ้น แต่ระบบควบคุมคุณภาพอาจจะโดยทีมงาน QA แยกต่างหากสามารถแก้ปัญหาคุณภาพมากเกินไป (และมันทำให้ความรู้สึกอาจจะมีทั้ง - อัตโนมัติและการทดสอบด้วยตนเอง)
Doc Brown

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

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

5

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


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

5

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

หากคุณหยุดพฤติกรรมของคอร์โดยทำการรีลีส1และคุณวางรีลีสนั้นลงในระบบการจัดการสิ่งประดิษฐ์ส่วนตัว2จากนั้นโครงการลูกค้าใด ๆ ก็สามารถประกาศการพึ่งพาคอร์รุ่นXและจะไม่ถูกทำลายโดยรีลีสถัดไปX + 1

จากนั้น "นโยบายการประกาศ" จะลดการมีไฟล์ CHANGES พร้อมกับแต่ละรุ่นหรือมีการประชุมทีมเพื่อประกาศคุณสมบัติทั้งหมดของแต่ละรุ่นหลัก

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

แก้ไข : ถ้าคุณไปตามธรรมเนียมปฏิบัติในส่วนระบบความหมายรุ่นแล้วการเปลี่ยนแปลงใด ๆ ในการเข้ากันไม่ได้ API หลักที่จะต้องมีการทำเครื่องหมายโดยการเปลี่ยนแปลงรุ่นใหญ่ นั่นคือเมื่อคุณเปลี่ยนพฤติกรรมของคอร์ที่มีอยู่ก่อนหน้านี้หรือลบบางสิ่งออกไปไม่ใช่แค่เพิ่มสิ่งใหม่ นักพัฒนาทราบว่าการอัปเดตจากเวอร์ชัน '1.1' เป็น '1.2' นั้นปลอดภัย แต่การเปลี่ยนจาก '1.X' เป็น '2.0' นั้นมีความเสี่ยงและต้องได้รับการตรวจสอบอย่างรอบคอบ

1: ฉันคิดว่านี่เรียกว่าอัญมณีในโลกของ Ruby
2: เทียบเท่ากับ Nexus ใน Java หรือ PyPI ใน Python


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

@DocBrown: ฉันเห็นด้วยกับคุณ แต่ฉันเขียนภายใต้สมมติฐานที่ว่านักพัฒนาทุกคนมีความร่วมมือและเติบโตขึ้นมา นี้ไม่ได้จะบอกว่าผมไม่ได้เห็นสิ่งที่คุณอธิบาย แต่ส่วนสำคัญของการทำให้ระบบมีความน่าเชื่อถือนั้นก็คือการมุ่งมั่นเพื่อความมั่นคง นอกจากนี้หากทีม A ต้องการเปลี่ยน X ในแกนกลางและทีม B จำเป็นต้องเปลี่ยน X ในแกนดังนั้น X อาจจะไม่ได้อยู่ในแกนกลาง ฉันคิดว่านั่นคือจุดอื่นของฉัน :)
logc

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

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

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

3

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

เหมือนกันสำหรับ TDD ฉันไม่เห็นว่ามันสามารถแก้ปัญหานี้ได้อย่างไร

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


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

2
ความคิดคือการมีชุดทดสอบหน่วยสำหรับแกนซึ่งเป็นส่วนหนึ่งของแกนที่มีผลงานจากทุกทีมไม่ได้แยกชุดทดสอบสำหรับแต่ละทีม
Doc Brown

2
@ SDD64: คุณสับสน "คุณยังไม่ต้องการมัน (ยัง)" (ซึ่งเป็นสิ่งที่ดีมาก) กับ "คุณไม่จำเป็นต้องทำความสะอาดรหัสของคุณ (ยัง)" - ซึ่งเป็นนิสัยที่แย่มาก และ IMHO ค่อนข้างตรงกันข้าม
Doc Brown

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

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

2

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


2

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

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

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

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

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


ก่อนที่เราจะย้ายผลิตภัณฑ์ของเราจาก Java ไปยัง RoR เราทำตามที่คุณแนะนำจริง ๆ เรามีแกน Java สำหรับลูกค้าทุกคน แต่ความต้องการของพวกเขา 'แตก' หนึ่งวันและเราต้องแยกมันออก ในสถานการณ์ดังกล่าวเราประสบปัญหาเช่น: 'เพื่อนลูกค้า Y มีคุณลักษณะหลักที่ดีเช่นนี้ น่าเสียดายที่เราไม่สามารถส่งไปยังลูกค้า Z ได้เพราะแกนหลักของพวกเขาไม่เข้ากัน ' ด้วย Rails เราอยากจะใช้นโยบาย 'หนึ่งหลักสำหรับทุกคน' อย่างเคร่งครัด ถ้าเป็นเช่นนั้นเรายังคงเสนอการเปลี่ยนแปลงที่รุนแรง แต่สิ่งเหล่านี้ไม่ได้รับการปรับปรุงจากลูกค้า
SDD64

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

1

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

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

รหัสหลอกเดิม:

def someFunction
   do original stuff
   return result
end

รหัสทดสอบในสถานที่ชั่วคราว:

def someFunctionNew
   new do stuff
   return result
end

def someFunctionOld
   do original stuff
   return result
end

def someFunction
   oldResult = someFunctionOld
   newResult = someFunctionNew
   check oldResult = newResult
   return newResult
end

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


1

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

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

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


1

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

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

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

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

คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับ CI เป็นกระบวนการสื่อสารที่นี่

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

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