ทำไม "vs" ไม่ใช่ "vs" คุณสามารถใช้การเขียนโปรแกรม Aspect Oriented เมื่อใช้ร่วมกับการเขียนโปรแกรมที่ใช้งานได้ แต่ยังใช้ร่วมกับ Object Oriented one ไม่ใช่ "vs" เป็น "การเขียนโปรแกรมเชิงมุมมองด้วยการเขียนโปรแกรมเชิงวัตถุ"
สำหรับฉัน AOP เป็น "meta-programming" บางประเภท ทุกสิ่งที่ AOP ทำได้ก็ทำได้โดยไม่ต้องเพิ่มรหัสอีก AOP เพียงช่วยให้คุณเขียนรหัสนี้
Wikipedia มีหนึ่งในตัวอย่างที่ดีที่สุดสำหรับการเขียนโปรแกรมเมตานี้ สมมติว่าคุณมีคลาสกราฟิกที่มีวิธี "set ... ()" มากมาย หลังจากแต่ละวิธีการตั้งค่าข้อมูลของกราฟิกที่มีการเปลี่ยนแปลงดังนั้นกราฟิกที่มีการเปลี่ยนแปลงและดังนั้นจึงต้องมีการปรับปรุงกราฟิกบนหน้าจอ สมมติว่าทาสีใหม่กราฟิกที่คุณต้องเรียกว่า "Display.update ()" วิธีคลาสสิกคือการแก้ปัญหานี้โดยการเพิ่มรหัสเพิ่มเติม ในตอนท้ายของแต่ละชุดวิธีการที่คุณเขียน
void set...(...) {
:
:
Display.update();
}
หากคุณมีวิธีการตั้งค่า 3 วิธีนั่นไม่ใช่ปัญหา หากคุณมี 200 (สมมุติ) มันเจ็บปวดอย่างมากที่จะเพิ่มสิ่งนี้ทุกที่ นอกจากนี้เมื่อใดก็ตามที่คุณเพิ่มวิธีการตั้งค่าใหม่คุณต้องแน่ใจว่าจะไม่ลืมการเพิ่มสิ่งนี้ไปยังจุดสิ้นสุดมิฉะนั้นคุณเพิ่งสร้างข้อผิดพลาด
AOP แก้ปัญหานี้โดยไม่ต้องเพิ่มโค้ดแทน แต่คุณเพิ่มมุมมอง:
after() : set() {
Display.update();
}
และนั่นมัน! แทนที่จะเขียนรหัสอัพเดตด้วยตัวเองคุณเพียงแค่บอกระบบว่าหลังจากถึงจุดที่กำหนด () แล้วมันจะต้องเรียกใช้รหัสนี้และมันจะเรียกใช้รหัสนี้ ไม่จำเป็นต้องอัปเดต 200 วิธีไม่จำเป็นต้องให้แน่ใจว่าคุณไม่ลืมที่จะเพิ่มรหัสนี้ในชุดวิธีการใหม่ นอกจากนี้คุณต้องมีจุดตัด:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
นั่นหมายความว่าอย่างไร? ซึ่งหมายความว่าถ้าวิธีการที่มีชื่อว่า "ชุด *" (* หมายถึงชื่อใด ๆ ที่อาจตามมาหลังจากชุด) โดยไม่คำนึงถึงสิ่งที่เป็นวิธีการส่งกลับ (ดอกจันแรก) หรือสิ่งที่พารามิเตอร์จะใช้เวลา (ดอกจันสาม) และมันเป็นวิธีการของ MyGraphicsClass และนี้ class เป็นส่วนหนึ่งของแพ็คเกจ "com.company. *" ดังนั้นนี่คือ pointcut ชุด () และรหัสแรกของเราบอกว่า " หลังจากใช้วิธีการใด ๆ ที่เป็นชุดจุดตัดแล้วให้เรียกใช้รหัสต่อไปนี้"
ดูว่า AOP แก้ปัญหาที่นี่ได้อย่างไร จริงๆแล้วทุกอย่างที่อธิบายที่นี่สามารถทำได้ในเวลารวบรวม ตัวประมวลผลล่วงหน้า AOP สามารถแก้ไขแหล่งที่มาของคุณ (เช่นการเพิ่ม Display.update () ไปยังจุดสิ้นสุดของทุกวิธี set-pointcut) ก่อนที่จะรวบรวมคลาสเอง
อย่างไรก็ตามตัวอย่างนี้ยังแสดงข้อเสียข้อใหญ่ของ AOP AOP กำลังทำสิ่งที่โปรแกรมเมอร์หลาย ๆ คนคิดว่าเป็น " Anti-Pattern " รูปแบบที่แน่นอนเรียกว่า " Action at a distance "
การดำเนินการในระยะไกลเป็นรูปแบบการต่อต้าน (ข้อผิดพลาดทั่วไปที่รู้จัก) ซึ่งพฤติกรรมในส่วนหนึ่งของโปรแกรมนั้นแตกต่างกันไปอย่างยากลำบากตามที่ยากหรือเป็นไปไม่ได้ในการระบุการดำเนินการในส่วนอื่นของโปรแกรม
สำหรับมือใหม่ในโครงการฉันอาจอ่านโค้ดของชุดวิธีการใด ๆ และพิจารณาว่ามันใช้งานไม่ได้เนื่องจากดูเหมือนว่าจะไม่อัปเดตจอแสดงผล ฉันไม่เห็นเพียงแค่ดูโค้ดของ set-method หลังจากที่ถูกประมวลผลแล้วโค้ดอื่น ๆ จะถูก "Magical" ถูกประมวลผลเพื่ออัพเดตการแสดงผล ฉันคิดว่านี่เป็นข้อเสียที่ร้ายแรง! โดยการเปลี่ยนแปลงวิธีการอาจมีข้อผิดพลาดแปลก ๆ ความเข้าใจเพิ่มเติมเกี่ยวกับการไหลของรหัสของรหัสที่สิ่งบางอย่างดูเหมือนจะทำงานได้อย่างถูกต้อง แต่ไม่ชัดเจน
ปรับปรุง
เพื่อชี้แจงว่า: บางคนอาจมีความรู้สึกที่ฉันพูดว่า AOP เป็นสิ่งที่ไม่ดีและไม่ควรใช้ นั่นไม่ใช่สิ่งที่ฉันพูด! AOP เป็นคุณสมบัติที่ยอดเยี่ยม ฉันแค่พูดว่า "ใช้อย่างระมัดระวัง" AOP จะทำให้เกิดปัญหาหากคุณรวมรหัสปกติและ AOP สำหรับAspectเดียวกันเท่านั้น ในตัวอย่างข้างต้นเรามีมุมมองในการปรับปรุงค่าของวัตถุกราฟิกและทาสีวัตถุที่ได้รับการปรับปรุง อันที่จริงแล้วเป็นแง่มุมเดียว การเข้ารหัสครึ่งหนึ่งของรหัสนี้เป็นรหัสปกติและอีกครึ่งหนึ่งเป็นรหัสคือสิ่งที่เพิ่มปัญหา
หากคุณใช้ AOP สำหรับแง่มุมที่แตกต่างอย่างสิ้นเชิงเช่นการบันทึกคุณจะไม่พบปัญหาเรื่องรูปแบบการต่อต้าน ในกรณีที่มือใหม่ของโครงการอาจสงสัยว่า "ข้อความบันทึกเหล่านี้มาจากที่ใดฉันไม่เห็นบันทึกการแสดงผลในรหัส" แต่นั่นไม่ใช่ปัญหาใหญ่ การเปลี่ยนแปลงที่เขาทำกับลอจิกของโปรแกรมแทบจะไม่ทำลายสิ่งอำนวยความสะดวกในการบันทึกและการเปลี่ยนแปลงที่เกิดขึ้นกับสิ่งอำนวยความสะดวกในการบันทึกจะแทบจะไม่ทำลายตรรกะของโปรแกรมของเขา การใช้ AOP สำหรับการบันทึกมีข้อดีคือรหัสโปรแกรมของคุณสามารถจดจ่อกับการทำสิ่งที่ควรทำและคุณยังสามารถมีการบันทึกที่ซับซ้อนโดยไม่ต้องมีรหัสของคุณเต็มไปด้วยข้อความบันทึกหลายร้อยทุกที่ นอกจากนี้เมื่อมีการนำรหัสใหม่ข้อความบันทึกอย่างน่าอัศจรรย์จะปรากฏในเวลาที่เหมาะสมพร้อมเนื้อหาที่ถูกต้อง
ดังนั้นการใช้งาน AOP ที่ดีในตัวอย่างของฉันคือการบันทึกทุกครั้งที่มีการอัพเดทค่าใด ๆ ผ่านวิธีการตั้งค่า สิ่งนี้จะไม่สร้างรูปแบบการต่อต้านและแทบจะไม่เคยเป็นสาเหตุของปัญหาใด ๆ
อาจกล่าวได้ว่าหากคุณสามารถใช้ AOP ในทางที่ผิดเพื่อสร้างปัญหามากมายมันเป็นความคิดที่ดีที่จะใช้มันทั้งหมด อย่างไรก็ตามเทคโนโลยีใดที่ไม่สามารถถูกทำร้ายได้? คุณสามารถใช้การห่อหุ้มข้อมูลในทางที่ผิดคุณสามารถละเมิดมรดก เทคโนโลยีการเขียนโปรแกรมที่เป็นประโยชน์ทุกอย่างสามารถถูกทารุณกรรมได้ พิจารณาภาษาการเขียนโปรแกรมเพื่อ จำกัด ให้มีเฉพาะคุณสมบัติที่ไม่สามารถใช้งานในทางที่ผิด; ภาษาที่สามารถใช้ฟีเจอร์ได้เฉพาะในตอนแรกที่ตั้งใจจะใช้เท่านั้น ภาษาดังกล่าวจะถูก จำกัด จนสามารถพิสูจน์ได้ถ้ามันสามารถใช้สำหรับการเขียนโปรแกรมในโลกแห่งความเป็นจริง