開支報告的例子表示了客戶機如何從服務器得到屬性
屬性可沿兩個方向傳遞
客戶機也可將新的類型傳遞給用戶
最簡單的例子就是如圖
所示的計算服務器
該服務程序可執行任意任務
這樣整個企業內的客戶機都能利用高端或專用計算機
任務由一個簡單的本地(非遠程)接口定義
public interface Task {
Object run();
}
運行時
它就會進行一些計算
並返回一個包含結果的對象
這完全是一般性的任務
幾乎所有計算任務都可在這個接口下實現
遠程接口ComputeServer也同樣簡單
import java
rmi
*;
public interface ComputeServer extends Remote {
Object compute(Task task) throws RemoteException;
}
這個遠程接口的唯一目的就是使客戶機創建一個Task (任務)對象
並把它發送給服務器執行
最後返回結果
該服務器的基本實現如下
import java
rmi
*;
import java
rmi
server
*;
public class ComputeServerImpl
extends UnicastRemoteObject
implements ComputeServer
{
public ComputeServerImpl() throws RemoteException { }
public Object compute(Task task) {
return task
run();
}
public static void main(String[] args) throws Exception {
// use the default
restrictive security manager
System
setSecurityManager(new RMISecurityManager());
ComputeServerImpl server = new ComputeServerImpl();
Naming
rebind(
ComputeServer
server);
System
out
println(
Ready to receive tasks
);
return;
}
}
如果您看一看compute方法就會發現
它非常簡單
它只是接受傳遞給它的對象
並返回計算的結果
main方法包括服務器的啟動代碼
它安裝了RMI的缺省安全管理程序
以防止他人存取本地系統
並創建可處理進入的請求的ComputeServerImpl對象
並將其與名字
ComputeServer
關聯
這時
服務器已經准備好接收要執行的任務
而main 也完成了其設置
如上所述
這實際上是一種全面和實用的服務
系統可以得到改進
比如
可添加要計算的參數
從而對使用服務程序的部門進行計費
但在很多情況下
上述接口和及其實現允許使用高端計算機進行遠程計算
這又?明了RMI的簡單性
如果您鍵入上述類
對其進行編譯
並啟動服務程序
您就擁有了能執行任意任務的運行計算服務器
下面介紹一個使用這種計算服務的例子
假定您購買了一個能運行大量計算操作應用程序的非常高端的系統
管理員可在該系統上啟動一個Java虛擬機
運行ComputeServerImpl對象
該對象現在就可接受要運行的任務
現在假定一個小組准備通過一組數據培訓一個神經網絡
以幫助制訂采購策略
他們可以采用的步驟如下
定義一個類
暫且稱之為PurchaseNet
它能接受一組數據
並運行培訓數據
返回一個經過培訓的神經網絡
PurchaseNet 將實現Task (任務)接口
並在其run方法中執行其工作
他們可能還需要一個Neuron類來描述所返回的網絡中的節點
而且很可能需要其它類來描述處理過程
run方法將返回一個由一組經過培訓的Neuron對象組成的NeuralNet對象
當這些類被編寫好並進行小規模測試時
用一個PurchaseNet 對象調用ComputeServer的compute方法
當ComputeServerImpl對象中的RMI系統接收到作為進入參數的 PurchaseNet對象時
它就下載PurchaseNet的實現
並調用該服務器的compute方法
並把該對象作為Task (任務)參數
Task
也就是PurchaseNet對象
將開始執行其執行程序
當執行程序需要諸如Neuron和NeuralNet等新的類時
它們可根據需要下載
所有計算都將在計算服務器上執行
而客戶機線程則等待結果
(客戶機系統上的另一個線程則會顯示
正在等待
光標或使用Java的內置並行機制執行另一個任務 )
當運行返回其NeuralNet對象時
這個對象將作為compute 方法的結果被傳遞回客戶機
這不需要在服務器上安裝其它軟件
所有必須完成的任務都由各部門在其自己的計算機上完成
隨後再根據需要傳遞給計算服務器主機
這個簡單的計算服務器體系結構為系統的分布式功能提供了功能強大的轉換能力
一項任務的計算可以被轉移到一個能為其提供最好支持的系統上完成
這樣的系統可以被用來
在ComputeServerImpl對象運行於有數據挖掘需要的主機上
支持數據挖掘應用程序
這樣可使您輕松地把任何計算移動到數據所在的地方
在從當前股票價格
發貨信息或其它實時信息等外部資源獲得直接數據的服務器上運行計算任務
通過運行ComputeServer (接受進入的請求並將其轉送到運行 ComputeServerImpl的負擔最小的服務器上)的不同實現
而將任務分布在多個服務器上
代理
因為RMI允許使用Java實現下載屬性
所以您可使用RMI 編寫代理系統
代理的最簡單格式如下
import java
rmi
*;
public interface AgentServer extends Remote {
void accept(Agent agent)
throws RemoteException
InvalidAgentException;
}
public interface Agent extends java
io
Serializable {
void run();
}
啟動一個代理也就創建了實現Agent (代理)接口
找到服務器
激活接受該代理對象的類
該代理的執行程序將被下載到服務器上運行
accept方法將啟動一個該代理的新線程
激活其run方法
然後返回
從而使該代理一直執行到run方法返回為止
代理可通過激活在另一台主機上運行的服務程序的accept方法而移植到該主機
而其本身則作為將被接受的代理來傳遞
並結束其在原來主機上的線程
面向對象的代碼重用與設計模式
面向對象的編程是一項允許代碼重用的強大技術
很多企業組織都使用面向對象的編程來減輕創建程序的負擔和提高系統的靈活性
RMI是完全面向對象的
信息被發送給遠程對象
而且對象可以被傳遞和返回
Design Patterns (設計模式)目前在描述面向對象設計的實踐活動中獲得了相當大的成功
首先是因為Design Patterns 的創新工作而使之大受歡迎
這些編程方式是一種正式描述解決某類特定問題的完整方法的途徑
所有這些設計模式都依賴於創建一個或多個抽象概念
這些抽象概念允許不同的實現
從而允許和增強軟件重用
軟件重用是面向對象技術的主要優勢
而設計模式則是促進重用的最受歡迎的技術之一
所有設計模式都依賴面向對象的多態性
這是對象( 如Task )擁有多個實現的能力
算法的普通部分(如compute 方法)不必知道使用了哪個實現
它只需知道得到一個對象後應該對該對象采取什麼操作
特別地
計算服務器就是Command (指令)模式的一個例子
它可使您將請求 (任務)表示為對象
並對其進行調度
只有當包括執行程序在內的完整對象能在客戶機和服務器之間傳遞時
才會存在這樣的多態性
DCE和DCOM等傳統的RPC系統以及CORBA等基於對象的RPC系統不能下載並執行程序
因為它們不能把真實對象作為參數傳遞
而只能傳遞數據
RMI可傳遞包括執行程序在內的所有類型
所以您可以在分布式計算解決方案中
而不僅僅是本地計算中使用面向對象的編程
包括設計方式
如果沒有RMI這樣完全面向對象的系統
那麼您就必須放棄很多分布式計算系統中的設計方式
以及面向對象的軟件重用的其它形式
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27171.html