Java中的代理设计模式

时间:2020-02-23 14:35:31  来源:igfitidea点击:

代理设计模式允许我们在实体对象上创建一个包装类。

包装类是代理的,控制对实际对象的访问,依次,我们可以向实际对象添加另外的函数而不更改真实对象的代码。

如gof所描述的:

"为另一个对象提供代理或者占位符来控制访问权限。
"

现实生活示例可以是IT用于Internet Access的代理服务器。
它可以访问Facebook,Twitter等内容等社交的访问权限,这些内容不与其有关。

何时使用它:

只要需要对对象的更复杂或者多才多艺的参考,就需要对象而不是简单的指针时需要代理。
在代理模式适用时是某种情况。

  • 远程代理为不同地址空间中的对象提供了本地代表。诸如Web服务或者REST资源的远程资源的接口。
  • 虚拟代理按需创建昂贵的对象。
  • 保护代理控件控制对原始对象的访问。当对象应该具有不同的访问权限时,支持代理是有用的。
  • 智能引用是替代裸指针在访问对象时执行其他操作的替换。
  • 在不更改现有类代码的情况下向现有类添加线程安全函数。

用于代理设计模式的UML图:

元素:

  • 代理
  • 维护一个引用,即允许代理访问真实主题。如果RealSubject和主题接口是相同的,则备注可以参考主题。
  • 提供与受试者相同的接口,以便代理可以代替真实主题。
  • 控制访问真实主题,可能负责创建和删除它。
  • 主题
  • 定义RealSubject和Proxy的公共接口,以便可以在预期的任何位置使用代理。
  • realsubject.
  • 定义代理代表的实体对象。

工作流程:

代理在适当的时候向前向RealSubject转发请求,具体取决于代理的种类。

例子:

让我们看看一个例子。
我正在拍摄保护代理。
在我们的示例中,我们有一个文件夹,我们可以其中执行各种操作,如复制,粘贴文件或者子文件夹。
在OOP条款中,我们有IFOLDER接口和文件夹类,它提供了PersionOperatons()方法,这些是现有的类和接口我们无法改变。
我们希望进一步指定仅具有授权的用户可以访问它并执行剪切或者复制文件和子文件夹等操作。

UML图表例如:

与上面的通用元素相比,我们有

  • folderproxy(代理)
  • 文件夹(realsubject)
  • iFolder(主题)

上述程序的Java代码:

ifolder.java(主题):

package org.igi.javapostsforlearning.designpatterns;
 
public interface IFolder {
 
    public void performOperations();
}

课后是我们的RealSubject类.LETS说我们无法改变它,但我们希望提供授权。
folder.java(realsubject):

package org.igi.javapostsforlearning.designpatterns;
 
public class Folder implements IFolder{
 
 public void performOperations()
 {
       //access folder and perform various operations like copy or cut files
  System.out.println("Performing operation on folder");
 }
 
}

以下类为文件夹类提供授权.IT检查用户名和密码,如果匹配,则只能访问文件夹。
folderproxy.java(代理):

package org.igi.javapostsforlearning.designpatterns;
 
public class FolderProxy implements IFolder{
 
 Folder folder;
 User user;
  
 public FolderProxy(User user) {
  this.user = user;
 }
 
 
 public void performOperations() {
  
  if(user.getUserName().equalsIgnoreCase("igi") && user.getPassword().equalsIgnoreCase("igi"))
  {
   folder=new Folder();
   folder.performOperations();
  }
  else
  {
   System.out.println("You don't have access to this folder");
  }
      }
}

user.java:

package org.igi.javapostsforlearning.designpatterns;
 
public class User {
 
 String userName;
 String password;
  
 public User(String userName, String password) {
  this.userName = userName;
  this.password = password;
 }
 
 public String getUserName() {
  return userName;
 }
 public String getPassword() {
  return password;
 }
 
}

proxydesignpatternmain.java:

package org.igi.javapostsforlearning.designpatterns;
 
public class ProxyDesignPatternMain {
 
 public static void main(String[] args) {
  
  //When you click on folder,Lets say a GUI form will ask for userName and password.
  //and this GUI will create this user object
  
  //If we give correct userName and password
  User user=new User("igi","igi");
  FolderProxy folderProxy=new FolderProxy(user);
  System.out.println("When userName and password are correct:");
  folderProxy.performOperations();
  System.out.println("**");
  //if we give wrong userName and Password
  User userWrong=new User("abc","abc");
  FolderProxy folderProxyWrong=new FolderProxy(userWrong);
  System.out.println("When userName and password are incorrect:");
  folderProxyWrong.performOperations();
 }
 
}

输出:

When userName and password are correct:
Performing operation on folder
**
When userName and password are incorrect:
You don't have access to this folder

因此,在没有更改文件夹类的情况下,我们为文件夹提供了对文件夹的身份验证。