กิจกรรมใช้สำหรับการเขียนโปรแกรม GUI เท่านั้นหรือไม่
คุณจัดการกับการเขียนโปรแกรมแบ็กเอนด์ปกติอย่างไรเมื่อมีบางอย่างเกิดขึ้นกับสิ่งอื่นนี้
กิจกรรมใช้สำหรับการเขียนโปรแกรม GUI เท่านั้นหรือไม่
คุณจัดการกับการเขียนโปรแกรมแบ็กเอนด์ปกติอย่างไรเมื่อมีบางอย่างเกิดขึ้นกับสิ่งอื่นนี้
คำตอบ:
Nope มันมีประโยชน์จริง ๆ สำหรับการใช้ Observers และตรวจสอบให้แน่ใจว่าคลาสนั้นใกล้เคียงกับการดัดแปลง
สมมติว่าเรามีวิธีการที่ลงทะเบียนผู้ใช้ใหม่
public void Register(user) {
db.Save(user);
}
จากนั้นมีคนตัดสินใจว่าควรส่งอีเมล เราสามารถทำสิ่งนี้:
public void Register(user) {
db.Save(user);
emailClient.Send(new RegistrationEmail(user));
}
แต่เราเพิ่งแก้ไขคลาสที่ควรจะปิดเพื่อแก้ไข น่าจะดีสำหรับรหัสหลอกง่าย ๆ นี้ แต่น่าจะเป็นหนทางสู่ความบ้าคลั่งในรหัสการผลิต นานแค่ไหนจนกระทั่งวิธีนี้คือ 30 บรรทัดของรหัสที่แทบจะไม่เกี่ยวข้องกับวัตถุประสงค์ดั้งเดิมของการสร้างผู้ใช้ใหม่?
มันยิ่งดีกว่าที่จะให้ชั้นเรียนทำหน้าที่หลักของมันและเพิ่มเหตุการณ์ให้กับใครก็ตามที่กำลังฟังว่ามีการลงทะเบียนผู้ใช้และพวกเขาสามารถดำเนินการใด ๆ ที่พวกเขาต้องทำ (เช่นส่งอีเมล)
public void Register(user) {
db.Save(user);
RaiseUserRegisteredEvent(user);
}
นี่ทำให้รหัสของเราสะอาดและยืดหยุ่น หนึ่งในสิ่งที่มักถูกมองข้ามของ OOP คือคลาสจะส่งข้อความถึงกัน เหตุการณ์เป็นข้อความเหล่านี้
Nope
ตัวอย่างคลาสสิกของเหตุการณ์ที่ใช้ในตรรกะที่ไม่ใช่ GUI เป็นทริกเกอร์ฐานข้อมูล
ทริกเกอร์คือรหัสที่ถูกเรียกใช้งานเมื่อมีเหตุการณ์เกิดขึ้น (INSERT, DELETE, ฯลฯ ) ดูเหมือนว่าเหตุการณ์สำหรับฉัน
นี่คือนิยามของวิกิพีเดียของเหตุการณ์:
ในการคำนวณเหตุการณ์คือการกระทำหรือเหตุการณ์ที่ซอฟต์แวร์รู้จักซึ่งอาจได้รับการจัดการโดยซอฟต์แวร์ เหตุการณ์คอมพิวเตอร์สามารถสร้างหรือเรียกใช้โดยระบบโดยผู้ใช้หรือในรูปแบบอื่น โดยทั่วไปแล้วเหตุการณ์จะได้รับการจัดการแบบซิงโครไนซ์กับโฟลว์ของโปรแกรมนั่นคือซอฟต์แวร์อาจมีสถานที่เฉพาะแห่งหนึ่งแห่งขึ้นไปซึ่งมีการจัดการเหตุการณ์บ่อยครั้งที่วนรอบเหตุการณ์ แหล่งที่มาของเหตุการณ์รวมถึงผู้ใช้ที่อาจโต้ตอบกับซอฟต์แวร์เช่นการกดแป้นบนแป้นพิมพ์ แหล่งอื่นคืออุปกรณ์ฮาร์ดแวร์เช่นตัวจับเวลา ซอฟต์แวร์ยังสามารถทริกเกอร์ชุดเหตุการณ์ของตัวเองเข้าไปในลูปเหตุการณ์เช่นเพื่อสื่อสารความสำเร็จของงาน ซอฟต์แวร์ที่เปลี่ยนแปลงพฤติกรรมในการตอบสนองต่อเหตุการณ์ถูกกล่าวว่าเป็นตัวขับเคลื่อนเหตุการณ์ซึ่งมักจะมีเป้าหมายในการโต้ตอบ
ไม่ใช่ทุกเหตุการณ์ที่ผู้ใช้สร้างขึ้น บางอย่างถูกสร้างขึ้นโดยตัวจับเวลาเช่นเดียวกับ crontab ของฐานข้อมูล INSERT อย่างที่ฉันพูดถึงก่อนหน้านี้
คำจำกัดความยังระบุว่าบางโปรแกรมหรือระบบคือ"เหตุการณ์ที่ขับเคลื่อนด้วยบ่อยครั้งโดยมีเป้าหมายในการโต้ตอบ"ซึ่งเราสามารถตรวจสอบได้ว่าวัตถุประสงค์หรือประโยชน์ของเหตุการณ์ไม่เพียง แต่ค่อนข้างบ่อยครั้งเพื่อให้การโต้ตอบ (เช่น GUIs แม้ว่าจะไม่จำเป็นต้องใช้ GUI แต่เนื่องจากโปรแกรม CLI ยังสามารถโต้ตอบได้)
การเขียนโปรแกรมตามเหตุการณ์นั้นใช้สำหรับการเขียนโปรแกรมเซิร์ฟเวอร์ที่มีประสิทธิภาพสูง
ที่ปริมาณงานเซิร์ฟเวอร์ทั่วไปเวลาส่วนใหญ่ในการประมวลผลผลลัพธ์มาจาก I / O ตัวอย่างเช่นการดึงข้อมูลออกจากฮาร์ดดิสก์ไดรฟ์ (7200 RPM) อาจใช้เวลานานถึง 8.3 ms สำหรับโปรเซสเซอร์ GHz ที่ทันสมัยซึ่งจะเท่ากับ ~ 1 ล้านรอบนาฬิกา หาก CPU ต้องรอข้อมูลในแต่ละครั้ง (ไม่ทำอะไรเลย) เราจะสูญเสียวงจรนาฬิกาจำนวนมาก
เทคนิคการเขียนโปรแกรมแบบดั้งเดิมได้รับรอบนี้โดยการแนะนำหลายหัวข้อ CPU พยายามรันเธรดหลายร้อยเธรดพร้อมกัน อย่างไรก็ตามปัญหาที่รุ่นนี้ก็คือว่าทุกครั้งที่มีสวิทช์ CPU ด้ายมันต้องใช้หลายร้อยรอบนาฬิกาเพื่อเปลี่ยนบริบท การสลับบริบทคือเมื่อ CPU คัดลอกหน่วยความจำเธรดโลคัลลงในรีจิสเตอร์ของ CPUและยังเก็บการลงทะเบียน / สถานะของเธรดเก่าไว้ใน RAM
นอกจากนี้แต่ละเธรดต้องใช้หน่วยความจำในปริมาณที่แน่นอนเพื่อจัดเก็บสถานะของมัน
วันนี้มีการผลักดันสำหรับเซิร์ฟเวอร์ที่มีเธรดเดียวที่ทำงานในลูป จากนั้นชิ้นงานจะถูกส่งไปยังปั๊มข้อความซึ่งทำหน้าที่เป็นคิวสำหรับเธรดเดี่ยว (คล้ายกับเธรด UI) แทนที่จะรอให้งานเสร็จสิ้นซีพียูจะตั้งค่าเหตุการณ์การเรียกกลับสำหรับการเข้าถึงฮาร์ดดิสก์ไดรฟ์ ซึ่งช่วยลดการสลับบริบท
ตัวอย่างที่ดีที่สุดของเซิร์ฟเวอร์ดังกล่าวคือNode.jsซึ่งแสดงให้เห็นว่าสามารถจัดการการเชื่อมต่อพร้อมกัน 1 ล้านกับฮาร์ดแวร์ที่ใช้งานง่ายในขณะที่เซิร์ฟเวอร์Java / Tomcatจะต่อสู้กับคนไม่กี่พันคน
เหตุการณ์ยังถูกใช้อย่างมากในการเขียนโปรแกรมเครือข่าย (เช่น Nginx) เพื่อหลีกเลี่ยงการวนลูปที่ยุ่งและมีค่าใช้จ่ายสูงและให้อินเทอร์เฟซใหม่ที่จะรู้ว่าเมื่อการดำเนินการบางอย่างพร้อมใช้งาน (I / O ข้อมูลเร่งด่วน ฯลฯ ) และนี่ก็เป็นวิธีการแก้ที่ปัญหา C10k
แนวคิดพื้นฐานคือให้ชุดซ็อกเก็ตระบบปฏิบัติการ (เช่นการเชื่อมต่อเครือข่าย) เพื่อตรวจสอบเหตุการณ์ทั้งหมดหรือเพียงบางอย่างที่คุณสนใจเป็นพิเศษ (เช่นข้อมูลที่มีให้สำหรับการอ่านเป็นต้น) เมื่อระบบปฏิบัติการตรวจพบกิจกรรมดังกล่าวในซ็อกเก็ตหนึ่งตัวในรายการคุณจะได้รับการแจ้งเตือนเหตุการณ์ที่คุณกำลังค้นหาโดย API ซึ่งคุณจะต้องเรียงลำดับว่ามาจากไหนและทำตามนั้น .
ตอนนี้เป็นมุมมองในระดับต่ำและเป็นนามธรรม อย่างไรก็ตามมีกรอบระดับสูงกว่ามากมายที่จัดการกับสิ่งนั้นในรูปแบบข้ามแพลตฟอร์ม: Twisted for Python, Boost.Asio สำหรับ C ++ หรือ libevent for C เข้ามาในใจของฉัน
ระบบฝังตัวมักขับเคลื่อนเหตุการณ์โดยเนื้อแท้แม้ว่าจะไม่ได้โปรแกรมอย่างชัดเจน
เหตุการณ์เหล่านี้มาจากสิ่งต่าง ๆ เช่นการขัดจังหวะฮาร์ดแวร์การกดปุ่มการอ่านแบบอะนาล็อกเป็นดิจิตอลการหมดเวลาของตัวจับเวลา ฯลฯ
ระบบฝังตัวที่ใช้พลังงานต่ำมีแนวโน้มที่จะเป็นตัวขับเคลื่อนเหตุการณ์ พวกเขาใช้เวลาส่วนใหญ่นอน (CPU นอนในโหมดพลังงานต่ำ) กำลังรอสิ่งที่จะเกิดขึ้น (ว่า "บางสิ่ง" เป็นเหตุการณ์)
หนึ่งในกรอบทั่วไปที่ได้รับความนิยมมากที่สุดสำหรับระบบฝังตัวที่ขับเคลื่อนด้วยเหตุการณ์คือQuantum Platform (QP) (QP ยังทำงานภายใต้ Linux, Windows และระบบปฏิบัติการยูนิกซ์ใด ๆ ที่คล้ายกัน) เครื่องจักรของรัฐนั้นเหมาะอย่างยิ่งสำหรับการเขียนโปรแกรมเชิงเหตุการณ์ เนื่องจากโปรแกรมไม่ได้ "เรียงตามลำดับ" ในความหมายทั่วไป แต่เป็นชุดของ "การเรียกกลับ" ที่ถูกเรียกขึ้นอยู่กับสถานะของระบบและเหตุการณ์ปัจจุบัน
ข้อความเหตุการณ์ Gregor Hohpe
สถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์ Gregor Hohpe
สถาปัตยกรรม SEDA , เวลส์, Culler, Brewer
คุณจัดการกับการเขียนโปรแกรมแบ็คเอนด์ปกติอย่างไรเมื่อมีบางอย่างเกิดขึ้นทำสิ่งอื่นนี้
เครื่องจักรสถานะ จำกัดเป็นวิธีการหนึ่งที่ใช้กันทั่วไป
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
ในระบบฝังตัวเหตุการณ์เกิดขึ้นระหว่างการขัดจังหวะ มีแหล่งขัดจังหวะมากมายตั้งแต่ตัวนับถึง I / O
นอกจากนี้ RTOS ก็สามารถมีกิจกรรมได้เช่นกัน ตัวอย่างหนึ่งกำลังรอข้อความจากงานอื่น
สำหรับระบบที่ไม่ได้ฝัง แต่สิ่งที่ฉันทำใน C # คือระบบ SCADA มีเหตุการณ์มากมายที่เชื่อมโยงกับสิ่งที่เกิดขึ้นในคลังสินค้าเมื่อโหลดไม่ได้โหลดส่วนหนึ่งของระบบที่สร้างเหตุการณ์และส่วนอื่นกำลังเขียนสถานะใหม่ไปยังฐานข้อมูล แน่นอนว่าเรามีไคลเอนต์ GUI บางตัว แต่มันก็แค่แสดงสถานะของฐานข้อมูลซึ่งสะท้อนถึงสถานะของคลังสินค้า ดังนั้นจึงเป็นซอฟต์แวร์เซิร์ฟเวอร์แบ็กเอนด์ตามเหตุการณ์และการทำเกลียว ค่อนข้างท้าทายในการพัฒนา