[GO] Proxy pattern in Java

Introduction

Introducing the design patterns of [GoF](https://ja.wikipedia.org/wiki/Gang of for _ (Information Engineering)) ["Introduction to Design Patterns Learned in the Augmented and Revised Java Language"]( https://www.amazon.co.jp/ Augmented and revised edition Introduction to design patterns learned in Java language-Hiroshi Yuki / dp / 4797327030 / ref = pd_lpo_sbs_14_t_0? _ Encoding = UTF8 & psc = 1 & refRID = 2ZE4GPYNN55JGDR5QMHP) I will summarize about.

Proxy pattern

What is Proxy

Translated into Japanese, it means "proxy". ** A pattern in which a substitute class performs some processing on behalf of the principal's class and generates the principal's class when the principal is really needed ** is called a ** Proxy pattern **. .. By applying this pattern, you can solve the problem that the initialization process, which takes a long time to generate your own class, takes a long time and causes dissatisfaction to the user.

Character

The Proxy pattern is used by the classes that appear in the class diagram below. image.png

Abstract class / interface

Implementation class

Concrete example

As a concrete example, it will be explained based on the following class. image.png

interface

-** Management Interface **

Management.java


public interface Management {
	void setReviewProjectName(String projectName); 

	String getReviewProjectName();

	void printReviewResult();
}

The Management interface defines a method to set / get the projectName and display the result of the review. The actual processing is implemented in the Manager class and ManagerProxy class described later. There is nothing particularly difficult.

Implementation class

-** Manager class **

Manager.java


import java.util.Random;

public class Manager implements Management {
	private String projectName;

	public Manager() {
		this.projectName = "Untitled case";
		heavyJob("Create an instance of Management and in Rv");
	}

	public Manager(String projectName) {
		this.projectName = projectName;
		heavyJob("Management instance(" + projectName + ")Generate and during Rv");
	}

	@Override
	public void setReviewProjectName(String projectName) {
		this.projectName = projectName;
	}

	@Override
	public String getReviewProjectName() {
		return projectName;
	}

	private void heavyJob(String msg) { // 1.Required at generation time(Setting)Heavy processing
		System.out.print(msg);
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
			System.out.print("・");
		}
		System.out.println("Rv completed.");
	}

	@Override
	public void printReviewResult() { // 2.Processing to sort and output the review result by random number
		System.out.println("----------Rv result----------");
		Random rnd = new Random();
		int ran = rnd.nextInt(10);
		if (ran < 5) {
			System.out.println(projectName + "Was rejected.\n");
		} else if (ran > 5) {
			System.out.println(projectName + "Has been approved.\n");
		}
	}

}

The Manager class is the class for the person. It does something unmanageable for the surrogate ManegerProxy class. Here, printReviewResult corresponds to that process. The points are the following two points. ** 1. ** It is necessary (setting) at the time of generation in the constructor, but it calls the heavyJob method, which is a time-consuming and heavy process. ** 2. ** Override printReviewResult and display the review result.

I will give a supplementary explanation. To generate the Manager class, you need to execute the heavyJob method by default. However, this process is heavy and time consuming, so it is a good idea to generate the Manager class until the process (printReviewResult) that cannot be handled by the ManegerProxy class acting as an agent is called. There is none. Therefore, in the ManegerProxy class described later, the process of only acquiring and setting the project name (getReviewProjectName, setReviewProjectName) is performed by the agent himself, and when printReviewResult is called, the manegerProxy is the person himself. Generate and set the Maneger` class.

-** ManagerProxy class **

ManagerProxy.java


public class ManagerProxy implements Management {
	private String projectName;
	private Manager real;

	public ManagerProxy() {
		this.projectName = "Untitled case";
	}

	public ManagerProxy(String projectName) {
		this.projectName = projectName;
	}

	@Override
	public synchronized void setReviewProjectName(String projectName) {
		// 1.If the role of the person is generated and set, the project name is set for the role of the person.
		if (real != null) {
			real.setReviewProjectName(projectName);
		}
		// 1.If the principal role is not created / set, set the project name to the proxy role.
		this.projectName = projectName;
	}

	@Override
	public String getReviewProjectName() {
		return projectName;
	}

	@Override
	public void printReviewResult() {
		realize();
		real.printReviewResult();
	}

	private synchronized void realize() {// 2.Generate / set the person's role when the person's role is not generated / set
		if (real == null) {
			real = new Manager(projectName);
		}
	}
}

The ManagerProxy class is a class that acts as a proxy for the Manager class. The points are the following two points. ** 1. ** Overriding setReviewProjectName. ** 2. ** After calling the realize method in the printReviewResult method, the printReviewResult method of the person himself is called.

I will explain in the supplement. When setReviewProjectName is called for 1., if the Manager class of the principal role is not set / generated, set the value to projectName of the ManagerProxy which is the proxy role. At this time, it can be said that the Manager class for the principal role has not been generated, and the ManagerProxy for the proxy role is performing the processing instead. Regarding 2., since the printReviewResult method is a process that cannot be handled by the proxy role, it is generated and set when the Manager class of the principal role is not generated and set.

Execution class

-** Client class **

Client.java


public class Client {
	public static void main(String[] args) {
		Management m1 = new ManagerProxy("A matter");
		System.out.println("Start project Rv.");
		System.out.println("The project in Rv" + m1.getReviewProjectName() + "is.");
		m1.setReviewProjectName("B matter");
		System.out.println("The project in Rv" + m1.getReviewProjectName() + "is.");
		m1.printReviewResult();

		Management m2 = new ManagerProxy();
		System.out.println("Start project Rv.");
		System.out.println("The project in Rv" + m2.getReviewProjectName() + "is.");
		m2.setReviewProjectName("C matter");
		System.out.println("The project in Rv" + m2.getReviewProjectName() + "is.");
		m2.printReviewResult();
	}
}

An instance of the ManagerProxy class is created and the name acquisition is set. After that, by calling the printReviewResult method, an instance of the Manager class that plays the role of the person is created and processed.

Execution result

The result of executing Client.java is as follows. You can see that the Rv result is randomly output by random numbers after the heavy processing (heavyJob) is executed.

Execution result


Start project Rv.
The project in Rv is A project.
The project in Rv is B project.
Management instance(B matter)Is generated, during Rv ... Rv completed.
----------Rv result----------
Case B has been rejected.

Start project Rv.
The project in Rv is an untitled project.
The project in Rv is C project.
Management instance(C matter)Is generated, during Rv ... Rv completed.
----------Rv result----------
Case C has been approved.

merit

The advantages of the proxy pattern are as follows. ** 1. ** The time required for initialization can be shortened and user convenience can be improved. ** 2. ** Parts can be made by separating the role of agent and the role of principal.

Summary

I learned about the Proxy pattern, which lets an agent, not the person, do the work until it's really needed. The sample code is uploaded below, so please refer to it if you like.

-Proxy sample code

In addition, other design patterns are summarized below, so please refer to them as well.

-[Updated from time to time] Summary of design patterns in Java

References

-[Introduction to Design Patterns Learned in the Augmented and Revised Java Language](https://www.amazon.co.jp/ Introduction to Design Patterns Learned in the Augmented and Revised Java Language-Hiroshi Yuki / dp / 4797327030 / ref = pd_lpo_sbs_14_t_0? _Encoding = UTF8 & psc = 1 & refRID = 2ZE4GPYNN55JGDR5QMHP)

Recommended Posts

Proxy pattern in Java
Singleton pattern in Java
Flyweight pattern in Java
Observer pattern in Java
Decorator pattern in Java
Prototype pattern in Java
Template Method pattern in Java
Chain of Responsibility pattern in Java
Learn the design pattern "Proxy" in Python
Singleton pattern in Python
Linux permissions in Java
Use DataFrame in Java
Visitor pattern in Python
Pip install in proxy environment
Implement Table Driven Test in Java
Detect and process signals in Java.
Implement the Singleton pattern in Python
Implemented bubble sort in Java (BubbleSort)
GoF java design pattern rough summary
Overlapping regular expressions in Python and Java
Learn the design pattern "Prototype" in Python
Learn the design pattern "Flyweight" in Python
Learn the design pattern "Memento" in Python
Express Python yield in JavaScript or Java
Apply Google Java Style formatter in IntelliJ
Learn the design pattern "Command" in Python
Get mail using Gmail API in Java
Learn the design pattern "Visitor" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Decorator" in Python
Learn the design pattern "Iterator" in Python
Learn the design pattern "Strategy" in Python
Learn the design pattern "State" in Python
Let's run a Bash script in Java
Learn the design pattern "Adapter" in Python
[Gang of Four] Design pattern learning --Proxy