傳遞屬性
前面我們講到
服務器定義的策略
圖
假定公司關於開支報告的政策發生改變
用客戶端安裝與政策有關的程序
您可要求服務器在每次向開支報告添加項目時檢查政策
您可在呈交報告時要求服務器對政策進行檢查
有了RMI
這表明
這是一種比任何靜態方法都更好的方法
所有客戶機不必暫停或用新的軟件來升級
服務器不必參與項目檢查工作
允許動態限制
使用戶能立刻看到錯誤
使客戶機在服務器上所能調用的方法的遠程接口定義如下
import java
public interface ExpenseServer extends Remote {
Policy getPolicy() throws RemoteException;
void submitReport(ExpenseReport report)
throws RemoteException
}
import語句輸入Java RMI包
它擴展了名為Remote的RMI接口
它的所有方法均拋出RemoteException
遠程方法還可拋出您所需要的任何其他例外
政策接口本身可聲明一種使客戶機知道能否在開支報告中添加一個項目的方法
public interface Policy {
void checkValid (Expenseentry entry)
throws PolicyViolationException;
}
如果該項目有效
Policy curPolicy = server
start a new expense report
show the GUI to the user
while (user keeps adding entries) {
try {
curPolicy
add the entry to the expense report
} catch (PolicyViolationException e) {
show the error to the user
}
}
server
當用戶請求客戶機軟件啟動一份新的開支報告時
import java
import java
class ExpenseServerImpl
extends UnicastRemoteObject
implements ExpenseServer
{
ExpenseServerImpl() throws RemoteException {
//
}
public Policy getPolicy() {
return new TodaysPolicy();
}
public void submitReport(ExpenseReport report) {
//
}
}
除基本程序包外
本文中討論的重要方法是getPolicy
public class TodaysPolicy implements Policy {
public void checkValid(ExpenseEntry entry)
throws PolicyViolationException
{
if (entry
return; // no receipt required
else if (entry.haveReceipt() == false) {
throw new PolicyViolationException;
}
}
}
TodaysPolicy進行檢查的目的是確保無收據的任何項目均少於20美元。TW.WInGWIT.cOm如果將來政策發生變化,僅少於20美元的餐費可不受“需要收據”政策的限制,則您可提供新的政策實現:
public class TomorrowsPolicy implements Policy {
public void checkValid(ExpenseEntry entry)
throws PolicyViolationException
{
if (entry.isMeal() && entry.dollars() < 20) {
return; // no receipt required
} else if (entry.haveReceipt() == false) {
throw new PolicyViolationException;
}
}
}
編寫這個類,並把它安裝在服務器上,然後告訴服務器開始提供TomorrowsPolicy對象,而非daysPolicy對象,這樣您的整個系統就會開始使用新的政策。當客戶機調用服務器的getPolicy方法時,客戶機的RMI就會檢查返回的對象是否為已知類型。每台客戶機首次遇到TomorrowsPolicy時,RMI就會在getPolicy返回前下載政策的實現。客戶機可輕松地開始增強這個新的政策。
RMI使用標准Java對象序列化機制傳遞對象。引用遠程對象參數作為遠程引用傳遞。如果向某方法提供的參數為原始類型或本機(非遠程)對象,則向服務器傳遞一個深副本。返回值也拾?照同樣的方式處理,只不過是沿其它方向。RMI可使用戶向本機對象傳遞和返回完整對象圖並為遠程對象傳遞和返回引用。
在真實的系統中,getPolicy方法可能會有一個可以識別用戶及開支報告類型(差旅、客戶關系等)的參數,這樣可使政策加以區別。您或者可以不要求單獨的政策和開支報告對象,但您可以有一種newExpenseReport方法,它可返回一個直接檢查政策的ExpenseReport對象。這最後一種策略可使您像修改政策一樣簡單地修改開支報告的內容--當公司決定需要把餐費劃分為早餐、午餐和晚餐項目,而且像上述修改政策一樣簡單地執行修改時--可編寫一個實現該報告的新類,客戶程序就會自動使用這個類。
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26634.html