代理模式(Proxy Pattern)之远程代理服务

代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问。


远程代理服务:Java使用RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。C#则采用Romting


场景:承接状态模式中的糖果贩卖机,通过代理模式及Remoting实现远程监控机器的剩余糖果数量,机器位置和机器状态。


//代理GumballMachine的类

    //代理模式,为限制GumballMachine的访问,将其包装为GumballMachineProxy代理
    //继承MarshalByRefObject类,才可以通过Remoting进行序列化传输。
    public class GumballMachineProxy :  MarshalByRefObject
    {
        GumballMachine gumballMachine;

        public GumballMachineProxy(GumballMachine gumballMachine)
        {
            this.gumballMachine = gumballMachine;
        }
        //获取糖果数量
        public int getCount()
        {
            return gumballMachine.getCount();
        }
        //获取机器位置
        public string getLocation()
        {
            return gumballMachine.getLocation();
        }
        //获取机器状态
        public 状态模式.State getState()
        {
            return gumballMachine.getState();
        }
    }
//监控机器的类

    public class GumballMonitor
    {
        GumballMachineProxy gumballMachine;

        public GumballMonitor(GumballMachineProxy gumballMachine)
        {
            this.gumballMachine = gumballMachine;
        }

        public void report()
        {
            Console.WriteLine("----GumballMachine Report----");
            Console.WriteLine("Current inventory:{0} gumballs", gumballMachine.getCount());
            Console.WriteLine("Gumball Machine:{0}",gumballMachine.getLocation());
            Console.WriteLine("Cuttent state:{0}", gumballMachine.getState().GetType().Name);
            Console.WriteLine("------------ End ------------\n");
        }
    }
//需要修改的类

    //因为需要传输状态类,所以状态基类改成抽象类并继承MarshalByRefObject
    public abstract class State : MarshalByRefObject
    {
        //投入硬币
        public abstract void insertQuarter();
        //退出硬币
        public abstract void ejectQuarter();
        //拨动曲柄
        public abstract void turnCrank();
        //施行
        public abstract void dispense();
    }
//服务端:糖果贩卖机

        static void Main(string[] args)
        {
            GumballMachine gumballMachine = new GumballMachine(ConfigurationManager.AppSettings.Get("MachineLocation"), 100);
            GumballMachineProxy machineProxy = new GumballMachineProxy(gumballMachine);
            int port = Convert.ToInt32(ConfigurationManager.AppSettings.Get("GumballMachineTcpChannelPort"));
            //定义访问接口
            TcpChannel tcpServerChannel = new TcpChannel(port);
            ChannelServices.RegisterChannel(tcpServerChannel, false);
            //将machineProxy作为服务辅助对象
            RemotingServices.Marshal(machineProxy, "GumballMachineProxy", typeof(GumballMachineProxy));

            while (gumballMachine.getCount() >= 0)
            {
                Console.WriteLine("操作提示:1.投币,2.摇杆,3.退币");
                string num = Console.ReadLine();
                if (num.Equals("1"))
                {
                    gumballMachine.insertQuarter();
                }
                else if (num.Equals("2"))
                {
                    gumballMachine.turnCrank();
                }
                else if (num.Equals("3"))
                {
                    gumballMachine.ejectQuarter();
                }
            }
        }
//客户端:监控控制台

        static void Main(string[] args)
        {
            TcpChannel tcpServerChannel = new TcpChannel(0);
            ChannelServices.RegisterChannel(tcpServerChannel, false);
            List<GumballMachineProxy> remoteobjs = new List<GumballMachineProxy>();
            remoteobjs.Add((GumballMachineProxy)Activator.GetObject(typeof(GumballMachineProxy), "tcp://192.168.1.43:8080/GumballMachineProxy"));
            remoteobjs.Add((GumballMachineProxy)Activator.GetObject(typeof(GumballMachineProxy), "tcp://192.168.1.42:8080/GumballMachineProxy"));
            while (true)
            {
                Console.WriteLine("查看GumballMachine报告,请按回车键:");
                Console.ReadLine();
                Console.Clear();
                for (int i = 0; i < remoteobjs.Count; i++)
                {
                    GumballMonitor gumballMotnitor = new GumballMonitor(remoteobjs[i]);
                    try
                    {
                        Console.WriteLine("编号({0})GumballMachine", i);
                        gumballMotnitor.report();
                    }
                    catch (RemotingException e)
                    {
                        Console.WriteLine("编号({0})GumballMachine:RemotingException;原因:{1};位置:{2}", i, e.Message, e.StackTrace);
                    }
                    catch (System.Net.Sockets.SocketException e)
                    {
                        Console.WriteLine("编号({0})GumballMachine:SocketException;原因:{1};位置:{2}", i, e.Message, e.StackTrace);
                    }

                }

            }
        }
//测试环境:将糖果贩卖机部署到局域网IP分别为42,43的机器上并运行,然后运行监控控制台程序

//测试结果:

1.对42的糖果贩卖进行投币操作


2.查看监视控制台


3.摇取糖果

4.再次查看监控报告







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值