• 代理模式


    本人最常用的模式是装饰模式,一直搞不太清楚其跟代理模式的区别,今天来区分一下。

    代理模式

    代理模式是结构设计模式之一,也是非常好理解的一种模式。根据GoF中所说:

    为其他的对象提供代理或者占位符,来控制其访问的权限

    从上面的定义就可以知道代理模式的场景主要是当我们需要提供访问访问控制的时候使用的。

    假设我们有一个类,要在一个系统上面运行一些命令。在服务器端这个类工作的很正常,但是如果我们想根据这个类做一个客户端程序,那么就会有一些问题。因为基于这个类实现的客户端程序也有相同的权限来删除系统文件或者更改一些你不想让它修改的配置等等。

    我们可以通过创建一个代理的类来支持客户端的访问控制。

    原执行类

    参考如下代码:

    package net.ethanpark.design.proxy;
    
    public interface CommandExecutor {
        public void runCommand(String cmd) throws Exception;
    }
    package net.ethanpark.design.proxy;
    
    import java.io.IOException;
    
    public class CommandExecutorImpl implements CommandExecutor {
    
        @Override
        public void runCommand(String cmd) throws IOException {
                    //some heavy implementation
            Runtime.getRuntime().exec(cmd);
            System.out.println("'" + cmd + "' command executed.");
        }
    }

    上面的代码就是原始的执行类,用来直接在系统上面执行命令用的。

    代理类

    现在我们可以提供一个功能:只有admin用户才有全部的权限,如果用户不是admin,那么则只能执行部分有限的命令。下面就是简单的代理类实现:

    package net.ethanpark.design.proxy;
    
    public class CommandExecutorProxy implements CommandExecutor {
    
        private boolean isAdmin;
        private CommandExecutor executor;
    
        public CommandExecutorProxy(User user){
            if(user.getUsername().equals("admin"))
                isAdmin=true;
            executor = new CommandExecutorImpl();
        }
    
        @Override
        public void runCommand(String cmd) throws Exception {
            if(isAdmin){
                executor.runCommand(cmd);
            }else{
                if(cmd.trim().startsWith("rm")){
                    throw new Exception("rm command is not allowed for non-admin users.");
                }else{
                    executor.runCommand(cmd);
                }
            }
        }
    }
    package net.ethanpark.design.proxy;
    
    public class User {
       private String username;
       private String password;
    
       public User(String username, String password) {
          this.username = username;
          this.password = password;
       }
    
       public String getUsername() {
          return username;
       }
    
       public void setUsername(String username) {
          this.username = username;
       }
    
       public String getPassword() {
          return password;
       }
    
       public void setPassword(String password) {
          this.password = password;
       }
    }

    测试类

    下面是测试类:

    package net.ethanpark.design.test;
    
    import net.ethanpark.design.proxy.CommandExecutor;
    import net.ethanpark.design.proxy.CommandExecutorProxy;
    
    public class ProxyPatternTest {
        public static void main(String[] args){
            CommandExecutor executor = new CommandExecutorProxy(new User("notAdmin", "some password"));
            try {
                executor.runCommand("ls -ltr");
                executor.runCommand(" rm -rf abc.pdf");
            } catch (Exception e) {
                System.out.println("Exception Message::"+e.getMessage());
            }
        }
    }

    现在运行测试代码,则输出如下:

    'ls -ltr' command executed.
    Exception Message::rm command is not allowed for non-admin users.

    代理模式通常用来控制访问或者为原有实现提供包裹实现来提高性能。
    Java RMI包就使用了代理模式,有兴趣的人可以参考源码。

  • 相关阅读:
    Sublime Text 乱码解决(Package Control 和 ConvertToUTF8插件安装)
    Hadoop搭建,上传文件时出现错误,没有到主机的路由
    Hadoop安装成功之后,访问不了web界面的50070端口怎么解决?
    centos7安装ifconfig命令
    Vmware Centos7 配置静态 ip 和 使宿主机和虚拟机互相 ping 通
    parallels desktop虚拟机与Mac共享网络设置方法
    NGINX轻松管理10万长连接
    Nginx upstream性能优化
    Linux性能调优、Linux集群与存储等
    Run time setting设置详解
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461507.html
Copyright © 2020-2023  润新知