วิธีการลดความยุ่งยากในการบำรุงรักษาของรหัสเหตุการณ์ขับเคลื่อน?


16

เมื่อใช้องค์ประกอบตามเหตุการณ์ฉันมักจะรู้สึกเจ็บปวดในช่วงการบำรุงรักษา

เนื่องจากโค้ดที่ถูกประมวลผลจะถูกแยกออกไปรอบ ๆ มันอาจเป็นเรื่องยากที่จะคิดว่าส่วนใดของโค้ดที่จะเกี่ยวข้องกับรันไทม์

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

แก้ไขจากความคิดเห็น: แม้ว่าจะมีแนวปฏิบัติที่ดีเช่นการมีแอพพลิเคชั่น Event Bus และตัวจัดการที่มอบหมายธุรกิจไปยังส่วนอื่น ๆ ของแอพมีช่วงเวลาที่รหัสเริ่มอ่านยากเพราะมีจำนวนมาก ตัวจัดการการลงทะเบียนจากสถานที่ต่าง ๆ (โดยเฉพาะอย่างยิ่งจริงเมื่อมีรถบัส)

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

//////////////
ตัวอย่าง

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

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

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

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

ในตอนท้ายของ
//////////////

ดังนั้นฉันจึงสงสัยว่าคนอื่นกำลังจัดการกับรหัสประเภทนี้อย่างไร ทั้งเมื่อเขียนและอ่านแล้ว

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


คุณหมายถึงนอกจากสร้างตรรกะออกจากตัวจัดการเหตุการณ์อีกหรือไม่
Telastyn

บันทึกว่าเกิดอะไรขึ้น

@Tastastyn ฉันไม่แน่ใจว่าจะเข้าใจสิ่งที่คุณหมายถึงโดย 'นอกเหนือจากการสร้างตรรกะออกจากการจัดการเหตุการณ์'
Guillaume

@Thorbjoern: ดูการปรับปรุงของฉัน
Guillaume

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

คำตอบ:


7

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

ที่นี่ฉันนำเสนอตัวอย่างง่ายๆซึ่งแก้ไขโดยรูปแบบนี้

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

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

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


7

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


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

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

3

ดังนั้นฉันจึงสงสัยว่าคนอื่นกำลังจัดการกับรหัสประเภทนี้อย่างไร ทั้งเมื่อเขียนและอ่านแล้ว

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

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

บางครั้งนักพัฒนาอยากให้ฟังก์ชั่น GUI ที่ต้องอาศัยเหตุการณ์เช่นนั้น แต่จริงๆแล้วไม่มีทางเลือกจริงที่ง่ายกว่ามาก

บรรทัดล่างนี่คือเทคนิคไม่เลวถ้าใช้อย่างชาญฉลาด


การออกแบบทางเลือกใด ๆ ของพวกเขาที่จะหลีกเลี่ยง
Guillaume

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

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

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

@ Guillaume ฉันคิดว่าคุณเป็นผู้ให้บริการด้านวิศวกรรมมากกว่า คำอธิบายข้างต้นของฉันเป็นจริงตามเหตุการณ์ GUI ส่วนใหญ่ คุณต้องการการประมวลผลชนิดนี้หรือไม่?
NoChance

3

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

ผลข้างเคียงที่ซับซ้อนกับกระแสควบคุมที่ซับซ้อน

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

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

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

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

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

ลดความซับซ้อนของโฟลว์ควบคุมหรือผลข้างเคียง

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

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

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

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


2

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

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

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

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


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

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

2

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

แต่คุณอาจต้องการที่จะมองไปที่เครื่องรัฐ Markup เวิร์กโฟลว์ตัวอย่าง

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

แต่ละเครื่องเวิร์กโฟลว์สถานะมีสองคุณสมบัติ: InitialStateName และ CompletedStateName เมื่ออินสแตนซ์ของเวิร์กโฟลว์เครื่องสถานะถูกสร้างขึ้นจะถูกใส่ลงในคุณสมบัติ InitialStateName เมื่อเครื่องสถานะถึงคุณสมบัติ CompletedStateName เครื่องจะเสร็จสิ้นการดำเนินการ


2
ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรที่จะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง
Thomas Owens

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

1

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

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

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