码迷,mamicode.com
首页 > 其他好文 > 详细

headFirst学习笔记之十一:代理模式(5.2)

时间:2015-05-02 16:27:41      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:

1.目前任务:

上一章的万能糖果机的CEO,希望我们能发给它一份库存以及机器状态的报告。(简直就是小cese,CEO一定会被我的编码能力折服的hiahiahia~)

(1)在上一章的代码中加入location变量(2)然后添加糖果机监视器这个类。有一个问题:我点击运行后控制台什么反应都没有,我也不能输入信息。这是什么情况?

 1 public class GumballMachine {
 2     String location;
 3     int count = 0;
 4     public GumballMachine(String location, int count) {
 5     super();
 6     //其他代码
 7     this.location = location;
 8     }
 9 
10     public String getLocation() {
11     return location;
12     }
13     
14     //其他方法
15 }
 1 import unit10.state.GumballMachine;
 2 
 3 public class GumballMonitor {
 4     GumballMachine machine;
 5 
 6     public GumballMonitor(GumballMachine machine) {
 7         super();
 8         this.machine = machine;
 9     }
10     
11     public void report(){
12         System.out.println("gumball machine: "+machine.getLocation());
13         System.out.println("current inventory: "+machine.getCount());
14         System.out.println("current state: "+machine.getState());
15     }
16 }
 1 import unit10.state.GumballMachine;
 2 
 3 public class GumballMachineTestDrive {
 4     public void main(String[] args){
 5         int count = 0;
 6         //利用命令行来传入位置和数目
 7         if(args.length<2){
 8             System.out.println("GumballMachine <name><inventory>");
 9             System.exit(1);
10         }
11         
12         count = Integer.parseInt(args[1]);
13         GumballMachine machine = new GumballMachine(args[0],count);
14         GumballMonitor monitor = new GumballMonitor(machine);
15         
16         monitor.report();
17         //其他测试代码
18     }
19 }

但是问题来了:CEO想要的是远程监控糖果机,而现在监视器和糖果机在同一个JVM上运行!

解决办法:远程代理。远程代理就好比是“远程对象的本地代表”。远程对象:活在不同java虚拟机(jvm)堆中。本地代表:可以由本地方法调用的对象,其行为会转发到远程对象中。这里的“本地堆”就是ceo的桌面,它其实是和代理在聊天,它以为他在和真正的糖果机聊天。"远程堆"就是糖果机,它才是真正做事的。

(1)了解RMI

(2)把gumballMachine变成远程服务,提供一些可被远程调用的方法。

(3)创建一个能和远程gumballMachine沟通的代理proxy(这里需要用到RMI),然后和监视系统GumballMonitor结合。

2.RMI

JAVA已经内置远程调用的功能了,我们只需要修改下代码,使其符合RMI的要求即可。

客户对象---客户辅助对象(stub)---服务辅助对象(skeleton)--服务对象

(1)将一个普通对象变成可以被远程客户调用的服务:

a.制作远程接口:客户辅助对象(stub)和服务对象实现此接口。

b.制作远程的实现:真正的行为实现。

c.利用rmic产生的stub和skeleton:这就是客户和服务的辅助类,当我们运行rmic工具时,这都会自动处理。

d.启动RMI registry:就像一个电话簿,所有注册的服务都在这里。

e.开启远程服务:注册服务,开始运行。

1 import java.rmi.Remote;
2 import java.rmi.RemoteException;
3 
4 public interface MyRemote extends Remote {
5     //因为远程方法调用会用到网络和I/O,所以必须考虑成有风险的
6     //方法的返回类型必须是primitive类型或者serializable类型,因为需要通过网络运送
7     public String sayHello() throws RemoteException;
8 }
 1 import java.rmi.Naming;
 2 import java.rmi.RemoteException;
 3 import java.rmi.server.UnicastRemoteObject;
 4 
 5 public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
 6 
 7     protected MyRemoteImpl() throws RemoteException {
 8         super();
 9     }
10 
11     public String sayHello(){
12         return "server says: hey";
13     }
14     
15     public static void main(String[] args){
16         try {
17             //新建一个远程对象
18             MyRemote service = new MyRemoteImpl();
19             //将远程对象绑定到RMI regstry(类似电话簿的东西)中,注册名为RemoteHello,
20             //用户client就通过这个名字去找对应的代理:“我要找名字叫做RemoteHello”的stub
21             Naming.rebind("RemoteHello", service);
22         } catch (Exception e) {
23             e.printStackTrace();
24         }
25     }
26 }

技术分享

技术分享

技术分享

我的环境变量是对的,所以还是不知道是什么原因。

已解决:书上的命令是%rmic,但是我要打rmic才是对的,%不需要,那只是它的输入提示符,不是命令部分的东西。

 

(2)获取sub对象:当服务为绑定到RMI registry中时,其实真正被绑定的是stub,所以可以通过lookup找出来。

 1 import java.rmi.*;
 2 
 3 public class MyRemoteClient {
 4     public static void main(String[] args){
 5         new MyRemoteClient().go();    
 6     }
 7 
 8     public void go() {
 9         try {
10             MyRemote service = (MyRemote) Naming.lookup("rmi://10.15.199.179/RemoteHello");
11             String s = service.sayHello();
12             System.out.println(s);
13         } catch (Exception e) {
14             e.printStackTrace();
15         }
16     }
17 }

3.让gumballMachine成为远程服务:

(1)为gumballMachine创建远程接口。

(2)确认接口方法的所有返回类型都是可序列化的:在这里state接口不是可序列化的,所以要extends Serializable。但是没完呢!上一章程序中,我们

(3)在gumballMachine中实现此接口。

1 import java.rmi.*;
2 import unit10.state.State;
3 
4 public interface GumballMachineRemote extends Remote {
5     public int getCount() throws RemoteException;
6     public String getLocation() throws RemoteException;
7     public State getState() throws RemoteException;
8 }
1 import java.io.Serializable;
2 
3 public interface State extends Serializable{
4     ...
5 }

 

headFirst学习笔记之十一:代理模式(5.2)

标签:

原文地址:http://www.cnblogs.com/liyuhui21310122/p/4472010.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!