1. โหมดตัวแทน
ตัวแทนคือบุคคลหรือสถาบันที่กระทำการในนามของบุคคลหรือสถาบันอื่น ในบางกรณี ไคลเอนต์ไม่ต้องการหรือไม่สามารถอ้างอิงออบเจ็กต์ได้โดยตรง และออบเจ็กต์พร็อกซีสามารถทำหน้าที่เป็นตัวกลางระหว่างไคลเอนต์และออบเจ็กต์เป้าหมายได้
รูปแบบพร็อกซีจัดเตรียมวัตถุพร็อกซีสำหรับวัตถุ และวัตถุพร็อกซีควบคุมการอ้างอิงไปยังวัตถุต้นฉบับ
ตัวอย่างในชีวิตจริง: คุณยุ่งอยู่กับการทำงานล่วงเวลาในช่วงปีใหม่และไม่มีเวลาซื้อตั๋วรถไฟ ในเวลานี้ คุณสามารถโทรติดต่อศูนย์จำหน่ายตั๋วใกล้เคียงและขอให้พวกเขาซื้อตั๋วรถไฟให้คุณกลับบ้านได้ เพิ่มค่าแรงพิเศษ แต่ควรชัดเจนว่าศูนย์จำหน่ายตั๋วไม่ได้ขายตั๋วจริงๆ มีเพียงสถานีรถไฟเท่านั้นที่ขายตั๋วได้ นี่เป็นสิ่งสำคัญมาก!
ในตัวอย่างข้างต้น คุณคือ "ลูกค้า" ศูนย์จำหน่ายตั๋วคือ "บทบาทตัวแทน" สถานีรถไฟคือ "บทบาทที่แท้จริง" และการขายตั๋วเรียกว่า "บทบาทนามธรรม"!
ตัวอย่างโค้ด JAVA ของโหมดเอเจนต์:
บทบาทนามธรรม: คลาสนามธรรมหรือส่วนต่อประสาน
คัดลอกรหัสรหัสดังต่อไปนี้:
อินเตอร์เฟซธุรกิจ
-
เป็นโมฆะ doAction();
-
บทบาทที่แท้จริง: ใช้อินเทอร์เฟซตรรกะทางธุรกิจอย่างแท้จริง
บทบาทตัวแทน: ไม่ได้ใช้อินเทอร์เฟซตรรกะทางธุรกิจ แต่เรียกบทบาทจริงเพื่อนำไปใช้
คัดลอกรหัสรหัสดังต่อไปนี้:
คลาส BusinessImplProxy ดำเนินธุรกิจ
-
BusinessImpl ส่วนตัวสอง;
doAction เป็นโมฆะสาธารณะ ()
-
ถ้า (bi==null)
-
bi = BusinessImpl ใหม่ ();
-
ทำก่อน();
bi.doAction();
ทำหลังจาก();
-
โมฆะสาธารณะ doBefore()
-
System.out.println("กำลังประมวลผลล่วงหน้า!");
-
โมฆะสาธารณะ doAfter()
-
System.out.println("ขั้นตอนหลังการประมวลผล!");
-
-
//คลาสทดสอบ
การทดสอบในชั้นเรียน
-
โมฆะสาธารณะคง main (String [] args)
-
//ตัวแปรอ้างอิงถูกกำหนดให้เป็นประเภทบทบาทนามธรรม
ธุรกิจ bi = BusinessImplProxy ใหม่ ();
bi.doAction();
-
-
คัดลอกรหัสรหัสดังต่อไปนี้:
<span></span>
ดังนั้นด้วยการสนับสนุนของ JVM คลาสพร็อกซี ("บทบาทของตัวแทน") จึงสามารถสร้างได้แบบไดนามิกในขณะรันไทม์ และเราสามารถแก้ปัญหาการขยายโค้ดในโหมดพร็อกซีข้างต้นได้ หลังจากใช้พร็อกซีแบบไดนามิกแล้ว "บทบาทของตัวแทน" จะไม่จำเป็น ที่จะสร้างขึ้นด้วยตนเอง ซึ่ง JVM สร้างขึ้นแบบไดนามิกขณะรันไทม์โดยการระบุพารามิเตอร์สามตัว: ตัวโหลดคลาส อาร์เรย์อินเทอร์เฟซ และตัวจัดการการโทร
ตัวอย่างโค้ด Java ของโหมดพร็อกซีไดนามิก:
คัดลอกรหัสรหัสดังต่อไปนี้:
นำเข้า java.lang.reflect.InvocationHandler;
นำเข้า java.lang.reflect.Proxy;
นำเข้า java.lang.reflect.Method;
//บทบาทนามธรรม: การใช้งาน Java Dynamic Proxy ปัจจุบันรองรับเฉพาะอินเทอร์เฟซเท่านั้นและไม่รองรับคลาสนามธรรม
อินเทอร์เฟซ BusinessFoo
-
เป็นโมฆะ foo();
-
อินเทอร์เฟซ BusinessBar
-
แถบสตริง (ข้อความสตริง);
-
//บทบาทที่แท้จริง: ใช้วิธีการเชิงตรรกะทางธุรกิจจริง ๆ
คลาส BusinessFooImpl ใช้งาน BusinessFoo
-
โมฆะสาธารณะ foo()
-
System.out.println("BusinessFooImpl.foo()");
-
-
คลาส BusinessBarImpl ใช้งาน BusinessBar
-
แถบสตริงสาธารณะ (ข้อความสตริง)
-
System.out.println("BusinessBarImpl.bar()");
ข้อความตอบกลับ;
-
-
// บทบาทไดนามิก: สร้างคลาสพร็อกซีแบบไดนามิก
คลาส BusinessImplProxy ใช้ InvocationHandler
-
วัตถุวัตถุส่วนตัว;
BusinessImplProxy() {
-
BusinessImplProxy (วัตถุวัตถุ) {
นี้.obj = obj;
-
การเรียกใช้วัตถุสาธารณะ (พร็อกซีวัตถุ, วิธีการวิธีการ, วัตถุ [] args) พ่น Throwable
-
ผลลัพธ์ของวัตถุ = null;
ทำก่อน();
ผลลัพธ์ = method.inurge (obj, args);
ทำหลังจาก();
ส่งคืนผลลัพธ์;
-
โมฆะสาธารณะ doBefore(){
System.out.println("ทำอะไรก่อนตรรกะทางธุรกิจ");
-
โมฆะสาธารณะ doAfter(){
System.out.println("ทำบางอย่างหลังจาก Business Logic");
-
โรงงานวัตถุคงที่สาธารณะ (Object obj)
-
คลาส cls = obj.getClass();
กลับ Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),BusinessImplProxy ใหม่(obj));
-
-
//คลาสทดสอบ
DynamicProxy ระดับสาธารณะ
-
โมฆะคงที่สาธารณะ main (String [] args) พ่น Throwable
-
BusinessFooImpl bfoo = BusinessFooImpl(); ใหม่
BusinessFoo bf = (BusinessFoo) BusinessImplProxy.factory(bfoo);
bf.foo();
System.out.println();
BusinessBarImpl bbar = BusinessBarImpl(); ใหม่
BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar);
ข้อความสตริง = bb.bar("สวัสดีชาวโลก");
System.out.println (ข้อความ);
-
-
คำอธิบายการไหลของโปรแกรม:
new BusinessFooImpl(); สร้าง "บทบาทจริง" ส่งต่อไปยังเมธอดของโรงงาน BusinessImplProxy.factory() จากนั้นเริ่มต้น "ตัวประมวลผลการร้องขอ" - คลาสที่ใช้ InvocationHandler และส่งคืนอินสแตนซ์คลาสพร็อกซีที่สร้างขึ้นแบบไดนามิก เนื่องจาก "บทบาทตัวแทน" ต้องใช้วิธีตรรกะทางธุรกิจที่ได้รับจาก "บทบาทนามธรรม" จึงสามารถแปลงลงไปเป็น BusinessBar และกำหนดให้กับการอ้างอิง bb ที่ชี้ไปที่ประเภท BusinessBar
เมธอด newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) ช่วยให้โปรแกรมเมอร์สามารถระบุพารามิเตอร์และส่งคืนคลาสพร็อกซีที่ต้องการแบบไดนามิก ในขณะที่เมธอดการเรียกใช้ (Object proxy, Method method, Object[] args) ถูกใช้โดย JVM ถูกเรียกแบบไดนามิกเมื่อรันไทม์ เมื่อดำเนินการเมธอด "bb.bar("Hello,World");" JVM จะกำหนด "ตัวจัดการการเรียกใช้" แบบไดนามิก ส่งผ่านพารามิเตอร์ไปยังการเรียกใช้ภายนอก และเรียก method.inrigg(obj, args) เพื่อดำเนินการจริง!
วิธีการ BusinessImplProxy.Factory คงที่ใช้เพื่อสร้างคลาสพร็อกซีแบบไดนามิก ("บทบาทตัวแทน") บทบาทพร็อกซีจะถูกสร้างขึ้นแบบไดนามิกที่รันไทม์ตามอินเทอร์เฟซตรรกะทางธุรกิจที่แตกต่างกัน BusinessFoo และ BusinessBar "บทบาทนามธรรม", "บทบาทตัวแทน" และตัวจัดการการร้องขอ (คลาสที่ใช้อินเทอร์เฟซ InvocationHandler) สามารถเปลี่ยนแปลงได้ทั้งหมด ดังนั้นไดนามิกพร็อกซีของ JAVA จึงทรงพลังมาก