設計模式: 自己手動寫一個代理模式
代理模式:為另一個物件提供一個替身或佔位符以訪問這個物件。代理模式為另一個物件提供代表,以便控制客戶對物件的訪問,管理訪問的方式有許多種。
遠端代理管理客戶和遠端物件之間的互動。
虛擬代理控制訪問例項化開銷大的物件。
保護代理基於呼叫者控制對物件方法的訪問。
代理模式有許多變體,例如:快取代理、同步代理、防火牆代理、寫入時複製代理。
Java內建的代理支援,可以根據需要動態建立代理,並將所有呼叫分配到所選的呼叫處理器(InvocationHandler)。
下面 的例子是一種保護代理
類圖:
原始碼如下:
package javaproxy; /** * 被代理者介面 * @author Arvon * */ public interface PersonBean { public String getName(); public String getGender(); public String getInterests(); public int getHotAndNotRating(); public void setHotAndNotRating(int rating); public void setInterests(String interests); public void setName(String name); public void setGender(String gender); }
package javaproxy; public class PersonBeanImpl implements PersonBean { String name; String gender; String interests; int rating, ratingCount =1; public PersonBeanImpl(String name, String gender, String interests, int rating) { super(); this.name = name; this.gender = gender; this.interests = interests; this.rating = rating; } @Override public String toString() { return "PersonBeanImpl [name=" + name + ", gender=" + gender + ", interests=" + interests + ", rating=" + getHotAndNotRating() + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getInterests() { return interests; } public void setInterests(String interests) { this.interests = interests; } @Override public int getHotAndNotRating() { return ratingCount==0?0:(rating/ratingCount); } public void setHotAndNotRating(int rating){ this.rating+=rating; ratingCount++; } }
package javaproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * InvocationHandler 負責處理代理類發來的請求(即代理類的呼叫) * @author Administrator * */ public class OwnerInvocationHandler implements InvocationHandler { PersonBean person; public OwnerInvocationHandler(PersonBean person) { super(); this.person = person; } /** * Parameters:proxy - the proxy instance that the method was invoked * onmethod - the Method instance corresponding to the interface method * invoked on the proxy instance. The declaring class of the Method object * will be the interface that the method was declared in, which may be a * superinterface of the proxy interface that the proxy class inherits the * method through.args - an array of objects containing the values of the * arguments passed in the method invocation on the proxy instance, or null * if interface method takes no arguments. Arguments of primitive types are * wrapped in instances of the appropriate primitive wrapper class, such as * java.lang.Integer or java.lang.Boolean.Returns:the value to return from * the method invocation on the proxy instance. If the declared return type * of the interface method is a primitive type, then the value returned by * this method must be an instance of the corresponding primitive wrapper * class; otherwise, it must be a type assignable to the declared return * type. If the value returned by this method is null and the interface * method's return type is primitive, then a NullPointerException will be * thrown by the method invocation on the proxy instance. If the value * returned by this method is otherwise not compatible with the interface * method's declared return type as described above, a ClassCastException * will be thrown by the method invocation on the proxy instance. */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException { try { if(method.getName().startsWith("get")) return method.invoke(person, args); //方法的執行者 person else if(method.getName().equals("setHotAndNotRating")) throw new IllegalAccessException(); else if(method.getName().startsWith("set")) return method.invoke(person, args); //方法的執行者 person } catch (Exception e) { // e.printStackTrace(); System.out.println("cannot set rating by owner proxy!"); } return null;//如果呼叫其它的方法一律不予處理 } }
package javaproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class NonOwnerInvocationHandler implements InvocationHandler{
PersonBean person;
public NonOwnerInvocationHandler(PersonBean person) {
super();
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if(method.getName().startsWith("get"))
return method.invoke(person, args); //方法的執行者 person
else if(method.getName().equals("setHotAndNotRating"))
return method.invoke(person, args);
else if(method.getName().startsWith("set"))//他人不能設定自己的資訊
throw new IllegalAccessException();
} catch (Exception e) {
System.out.println("cannot set infos from nonowner proxy...");
}
return null;//如果呼叫其它的方法一律不予處理
}
}
package javaproxy;
import java.lang.reflect.Proxy;
/**
* 動態產生代理類
* @author Administrator
*
*/
public class ProxyHelper {
/**
* Returns an instance of a proxy class for the specified interfaces that
* dispatches method invocations to the specified invocation handler.
* @param person
* @return
*/
public static PersonBean getOwnerProxy(PersonBean person) {
return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(),
new OwnerInvocationHandler(person));
}
public static PersonBean getNonOwnerProxy(PersonBean person) {
return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(),
new NonOwnerInvocationHandler(person));
}
}
package javaproxy;
/**
* 測試類
* @author Administrator
*
*/
public class ProxyTest {
public static void main(String[] args) {
PersonBean person = new PersonBeanImpl("Jay", "F", "Java", 7);
System.out.println(person);
//動態地產生代理類ownerProxy (代理類ownerProxy實現了PersonBean介面)
PersonBean ownerProxy = ProxyHelper.getOwnerProxy(person);
System.out.println("Name is "+ownerProxy.getName());
//代理類的方法setInterests被呼叫 代理ownerProxy會把這個呼叫轉發給OwnerInvocationHandler
//ownerProxy 被例項化的時候指定的呼叫處理器是OwnerInvocationHandler
// 接著 OwnerInvocationHandler 呼叫它自己的invoke方法
//OwnerInvocationHandler 可能會轉發給被代理者PersonBean person 處理,如 return method.invoke(person, args); //方法的執行者 person
// 也可能做其他的處理 如丟擲異常
ownerProxy.setInterests("python");
System.out.println(person);
try {
ownerProxy.setHotAndNotRating(8);
} catch (Exception e) {
}
PersonBean nonOwnerProxy = ProxyHelper.getNonOwnerProxy(person);
System.out.println("Name is "+nonOwnerProxy.getName());
try {
nonOwnerProxy.setHotAndNotRating(9);
nonOwnerProxy.setInterests("python");
} catch (Exception e) {
}
System.out.println(person);
}
}
程式的輸出:
PersonBeanImpl [name=Jay, gender=F, interests=Java, rating=7]
Name is Jay
PersonBeanImpl [name=Jay, gender=F, interests=python, rating=7]
cannot set rating by owner proxy!
Name is Jay
cannot set infos from nonowner proxy...
PersonBeanImpl [name=Jay, gender=F, interests=python, rating=8]
相關推薦
設計模式: 自己手動寫一個代理模式
代理模式:為另一個物件提供一個替身或佔位符以訪問這個物件。代理模式為另一個物件提供代表,以便控制客戶對物件的訪問,管理訪問的方式有許多種。 遠端代理管理客戶和遠端物件之間的互動。 虛擬代理控制訪問例項化開銷大的物件。 保護代理基於呼叫者控制對物件方法的訪問。 代理模式有許多
設計模式: 自己手動實現一個觀察者設計模式
package rgs name gree 觀察者設計模式 forecast server 它的 upd 觀察者模式: 定義了對象之間的一對多依賴,這樣一來。當一個對象(被觀察者)改變狀態時,它的全部依賴者(觀察者)都會收到通知並自己主動更新。 在觀察者模式中,會
較底層程式設計:自己動手寫一個C語言編譯器
今天呢,我們就來自己動手編寫一個編譯器,學習一下較為底層的程式設計方式,是一種學習計算機到底是如何工作的非常有效方法。 編譯器通常被看作是十分複雜的工程。事實上,編寫一個產品級的編譯器也確實是一個龐大的任務。但是寫一個小巧可用的編譯器卻不是這麼困難。 祕訣就是首先去找到一個
ROS學習筆記(一):自己動手寫一個ROS程式
最近老闆安排任務,要把ROS框架在ARM+FPGA平臺上實現。但是使用ROS建立程式步驟繁瑣,所以這次將官方文件上面的Demo簡化寫下來,方便以後檢視。 ROS版本:Hydro Linux版本:Ubuntu12.04 在開始第一個ROS(Robot Operating Sy
自己手動寫一個簡單的bs結構
拋去web框架,自己手寫一個BS請求響應過程: 自己建立一個資料夾test,包含一個hello.html 和一個webserver.py 自己在html檔案裡面寫一些標籤 下面是webserver.py的主要內容: import os from
多執行緒設計模式:第三篇 - 生產者-消費者模式和讀寫鎖模式
一,生產者-消費者模式 生產者-消費者模式是比較常見的一種模式,當生產者和消費者都只有一個的時候,這種模式也被稱為 Pipe模式,即管道模式。 &nb
設計模式(二):自己動手使用“觀察者模式”實現通知機制
在之前釋出Objective-C系列部落格的時候,其中提到過OC的通知機制,請參考《Objective-C中的老闆是這樣發通知的(Notification)》這篇部落格。在之前關於Notification的部落格中,只介紹了Foundation框架中的通知的使用方式。正如前面部落格中提到的那樣,通知是“一對多
「補課」進行時:設計模式(5)——從 LOL 中學習代理模式
![](https://cdn.geekdigging.com/DesignPatterns/java_design_pattern.jpg) ## 1. 前文彙總 [「補課」進行時:設計模式系列](https://www.geekdigging.com/category/%e8%ae%be%e8%ae%
自己動手寫一個自動登錄腳本gg
簡單 只需要 自己 不同 enum -s class rep 使用 1.下載一個sshpass工具 2.安裝sshpass,安裝到tools文件夾 3.把tools文件夾的路徑加入到/etc/bashrc vim /etc/bashrc
<四>讀<<大話設計模式>>之代理模式
flow 編程 運行 應該 nts popu rac gif 通過 代理模式我想大家即便不熟悉也都聽過吧,從字面意思上看就是替別人幹活的,比方代理商。在項目的實際應用中也有非常多地方用到。比方spring通過代理模式生成對象等。 代理模式的書
傳智:自己簡單實現一個struts2框架的demo
throws for request 運行 本地化 color ray run main struts2的結構圖: 代碼實現: 組織結構: 主要代碼: package cn.itcast.config; import org.apache.log4j.Logg
五:用JAVA寫一個阿裏雲VPC Open API調用程序
外部jar包 ef7 dac java 方式 命令 pro ng- 自動化管理 用JAVA寫一個阿裏雲VPC Open API調用程序 摘要:用JAVA拼出來Open API的URL 引言 VPC提供了豐富的API接口,讓網絡工程是可以通過API調用的方式
python 1-2+3-4....99=? 這裏的題,我看到別人的寫法,五花八門的,自己也寫一個
blog sta 裏的 and str 想象力 pos 問題 就是 f = ""s = ""i = 1sum = 0while i < 100: if i %2 == 1 and i < 99: f = "-"
設計模式:學習筆記(4)——建造者模式
receiver temp pla his AI 技術 bubuko 電子 中一 設計模式:學習筆記(4)——建造者模式 概述 建造者模式 建造者模式是較為復雜的創建型模式,它將客戶端與包含多個組成部分(或部件)的復雜對象的創建過程分離,客戶端無須知道復雜對象的內部組成
設計模式:學習筆記(6)——抽象工廠模式
方法 組成 pat AR ID 指定 ride 抽象工廠模式 nds 設計模式:學習筆記(6)——抽象工廠模式 快速開始 介紹 抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創建其他工廠。該超級工廠又稱為其他工廠的工廠。這種類型的設計
設計模式:學習筆記(10)——適配器模式
light .com rgs strong 接口 可能 兼容 不能 pan 設計模式:學習筆記(10)——適配器模式 引入適配器模式 我們身邊的適配器 適配器是什麽,你一定不難理解,因為現實中到處都是。比方說:如果你需要在歐洲國家使用美國制作的筆記本電腦,你可能需要一個交
自己動手寫一個單鏈表
兩個指針 isl linklist nextn mob 內部 數組 nds pty 文章有不當之處,歡迎指正,如果喜歡微信閱讀,你也可以關註我的微信公眾號:好好學java,獲取優質學習資源。 一、概述 單向鏈表(單鏈表)是鏈表的一種,其特點是鏈表的鏈接方向是單向的,對鏈表
【原創】自己動手寫一個服務網關
exception 負責 lis world 前置 create ble ddr load 引言 什麽是網關?為什麽需要使用網關? 如圖所示,在不使用網關的情況下,我們的服務是直接暴露給服務調用方。當調用方增多,勢必需要添加定制化訪問權限、校驗等邏輯。當添加API網關後,
設計模式:裝飾器(Decorator)模式
讓我 分享圖片 底部 .com 一件事 輸出 PE 新的 int 設計模式:裝飾器(Decorator)模式 一、前言 裝飾器模式也是一種非常重要的模式,在Java以及程序設計中占據著重要的地位。比如Java的數據流處理,我們可能看到數據流經過不同的類的包裝和包裹,最
設計模式:觀察者(Observer)模式
image 強制轉換 trace vat PE sta obs observer -a 設計模式:觀察者(Observer)模式 一、前言 觀察者模式其實最好的名稱應該是“發布訂閱”模式,和我們現在大數據之中的發布訂閱方式比較類似,但是也有區別的地方,在上一個設計模式,