代理模式-远程代理(学习笔记2021.09.10)

代理模式-远程代理(学习笔记2021.09.10)

前言:

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

**意图:**为其他对象提供一种代理以控制对这个对象的访问。

**主要解决:**在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

**何时使用:**想在访问一个类时做一些控制。

**如何解决:**增加中间层。

**关键代码:**实现与被代理类组合。

应用实例: 1、Windows 里面的快捷方式。 2、猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。 3、买火车票不一定在火车站买,也可以去代售点。 4、spring aop。

优点: 1、职责清晰。 2、高扩展性。 3、智能化。

缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

**使用场景:**按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。

注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

前提条件

在之前的实现状态模式中, 糖果机公司的CEO又出了新需求,

他需要在本地的电脑上, 知道远程糖果机的状态、剩余糖果数量等等

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WNWzt3lu-1631276545500)(https://z3.ax1x.com/2021/09/10/hjzf5n.md.png)]

远程代理说明:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KbUgHeiL-1631276545502)(https://z3.ax1x.com/2021/09/10/hvS9KO.md.png)]

一个简单的远程代理服务演示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-joqYCM6P-1631276545504)(https://z3.ax1x.com/2021/09/10/hvk9fJ.md.png)]

下面使用远程代理模式实现远程监控糖果机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KewGUnQF-1631276545511)(https://z3.ax1x.com/2021/09/10/hvV8n1.md.png)]

1.0 改造糖果机GumballMachine

使其可以接受远程服务调用

1- 为糖果机创建一个可远程调用的服务接口

2- 接口定义调用的方法, 并且所有传输的对象都是可正常序列化与反序列化

3- 糖果机GumballMachine实现该接口

// 1、2- 提供远程调用那些方法的服务接口, 继承rmi使其可以注册到rmi服务中心
public interface GumballMachineRemote extends Remote {
    int getCount() throws RemoteException;
    String getLocation() throws RemoteException;
    // 该类型, 里面需要实现 public interface State extends Serializable
    State getState() throws RemoteException;
}

State类或者其所有实现类, 对应不想序列化进行传输发送的, 使用其关键字 private transient GumballMachine gumballMachine;

/** 3- 糖果机  我们实现了GumballMachineRemote, 但是需要明确其当成服务使用, 并处理网络上的请求, 需要继承UnicastRemoteObject**/
public class GumballMachine extends UnicastRemoteObject implements GumballMachineRemote {
    /**
     * 每种状态对应需要操作的行为
     */
    State soldOutState;
    State noQuarterState;
    State hasQuarterState;
    State soldState;

    /**
     * 真实获取到然后执行的对应状态的操作行为
     **/
    State state;
    int count = 0;

    //  构造器需要抛出异常, 因为父类的构造器抛也是抛出的异常
    public GumballMachine(int port,int numberGumballs) throws RemoteException{
        // 初始化每一种状态对应需要操作的行为
        soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);

        this.count = numberGumballs;
        // 当糖果数量大于0, 转换真实获取到然后执行的对应的没有投钱操作行为
        if (numberGumballs > 0) {
            state = noQuarterState;
        } else {
            // 当糖果数量小于0, 转换真实获取到然后执行的对应的没有货物操作行为
            state = soldOutState;
        }
    }

2.0 注册到RMI

打开CMD命令, 输入: rmiregistry 调起JDK内置的 RMI服务,

然后在运行rmi注册服务代码

@Test
    public void myEST() throws Exception {
        try {
            synchronized (GumballMachineRemote.class) {
                // 本地主机上的远程对象注册表Registry的实例,默认端口8090
                LocateRegistry.createRegistry(8090);
                // 创建一个远程对象
                GumballMachineRemote gumballMachineRemote = new GumballMachine(2);
                // 把远程对象注册到RMI注册服务器上,并命名为gumballMachineRemote
                Naming.bind("rmi://localhost:8090/gumballMachineRemote", gumballMachineRemote);
                System.out.println("======= 启动RMI服务成功! =======");
                GumballMachineRemote.class.wait();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

到此,我们的服务提供就完毕

3.0 进行消费服务, 打印糖果机状态

@Test
    public void applicationTest() throws Exception {
        GumballMachineRemote remote = (GumballMachineRemote) Naming.lookup("rmi://localhost:8090/gumballMachineRemote");
        System.out.println(remote.getCount());
        System.out.println(remote.getLocation());
    }
//  public void myEST() throws Exception {
2
深圳地区

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZycNMonU-1631276545512)(https://z3.ax1x.com/2021/09/10/hvKgNq.md.png)]

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懵懵懂懂程序员

如果节省了你的时间, 请鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值