“This is the 24th day of my participation in the August Genwen Challenge.More challenges in August”
What is delegation mode?
The Delegate Pattern, also known as the Delegate Pattern, is an object-oriented design Pattern that allows object composition to achieve the same code reuse as inheritance. Its basic function is responsible for the call and assignment of tasks, is a special static processing agent, can be understood as full proxy, but the proxy mode focuses on the process, while the delegation mode focuses on the results. The delegate pattern is a behavioral pattern and not one of goF’s 23 design patterns.
Roles involved in the delegate pattern
Let’s start with the class diagram:
From the class diagram, we can see that the delegate pattern has three participating roles:
- Abstract Task role (Task) : Defines an abstract interface that has several implementation classes.
- Delegate: Is responsible for making decisions between specific role instances about how to invoke specific implementation methods.
- Concrete: The role that actually performs the task.
The application of delegation mode in business scenarios
In real life, delegation often occurs. For example, the Boss assigns tasks to the project manager, and the project manager will assign tasks to each employee according to the actual situation. After the employee completes the task, the project manager will report the work progress and results to the Boss.
We use code to model the business scenario and create the IEmployee interface:
public interface IEmployee {
void doing(String task);
}
Copy the code
Create the employee EmployeeA class:
public class EmployeeA implements IEmployee {
protected String goodAt = "Programming";
@Override
public void doing(String task) {
System.out.println("I'm employee A. I'm good at it." + goodAt + "Do it now." + task + "Work"); }}Copy the code
Create employee EmployeeB class:
public class EmployeeB implements IEmployee {
protected String goodAt = "Graphic Design";
@Override
public void doing(String task) {
System.out.println("I'm employee B. I'm good at it." + goodAt + "Do it now." + task + "Work"); }}Copy the code
Create the project Manager Leader class:
public class Leader implements IEmployee {
private Map<String, IEmployee> employeeMap = new HashMap<>();
public Leader(a) {
employeeMap.put("Crawlers".new EmployeeA());
employeeMap.put("Illustration".new EmployeeB());
}
@Override
public void doing(String task) {
if(! employeeMap.containsKey(task)) { System.out.println("This mission" + task + "Out of my depth.");
return; } employeeMap.get(task).doing(task); }}Copy the code
Create Boss class and command:
public class Boss {
public void command(String task, Leader leader) { leader.doing(task); }}Copy the code
Test code:
public class Test {
public static void main(String[] args) {
Boss boss = new Boss();
Leader leader = new Leader();
boss.command("Crawlers", leader);
boss.command("Illustration", leader);
boss.command("Liao sister", leader); }}Copy the code
The running results are as follows:
Through the above code, a vivid restoration of the project manager to assign the work of the business scenario, is also a vivid embodiment of the delegation pattern.
Four, delegation mode in the source code
There is a typical delegate in the JDK, and it is well known that the JVM uses parental delegate mode to load classes. What about this? When a class loader loads a class, it delegates the request to its parent to execute it. If the parent still has a parent, it delegates up until the top level starts the class loader. If the parent class loader is able to complete the class load, it returns successfully, and if the parent class loader is unable to complete the load, the subclass loader attempts to load itself. You can see from the definition that the parent delegate loading model, when a class loader loads a class, it first delegates to the parent class loader instead of loading itself. Let’s look at the source code for the loadClass() method, which is in the ClassLoader. A parent is defined in this class for the following class loading.
public abstract class ClassLoader {...private finalClassLoader parent; .protectedClass<? > loadClass(String name,boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loadedClass<? > c = findLoadedClass(name);if (c == null) {
long t0 = System.nanoTime();
try {
if(parent ! =null) {
c = parent.loadClass(name, false);
} else{ c = findBootstrapClassOrNull(name); }}catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); }}if (resolve) {
resolveClass(c);
}
returnc; }}}Copy the code
Look at the below delegation model application in the Spring, the Spring IOC, the call doRegisterBeanDefinitions () method, namely BeanDefinition to register in the process, Sets BeanDefinitionParserDelegate type of the Delegate object to this. Deledate, and the object as a parameter to parseBeanDefinitions (root, enclosing the Delegate), Then the main parsing is done using the delegate as the main character, as you can see in the code below:
DefaultBeanDefinitionDocumentReader class:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element)node;
if (delegate.isDefaultNamespace(ele)) {
this.parseDefaultElement(ele, delegate);
} else{ delegate.parseCustomElement(ele); }}}}else{ delegate.parseCustomElement(root); }}Copy the code
The only way to get to the Bean registration part is to go to parseDefaultElement(ele,delegate) and actually register the node of the Bean for different node types. Will delegate to parseBeanDefinitionElement element, got a BeanDefinitionHolder type of object, after complete real registered through this object to the operation of the Factory.
Advantages and disadvantages of the delegation model
Advantages:
- Task delegation can refine a large task, and then follow up the task through unified management of the completion of these sub-tasks, which can accelerate the efficiency of task execution.
Disadvantages:
- Task delegation methods need to be changed according to the complexity of the task. In the case of complex tasks, multiple delegation may be required, which may cause chaos.
Six, friendship links
Design Patterns – Factory Patterns learning tour
Design Patterns – a learning tour of singleton patterns
Design Patterns – A learning journey of prototyping patterns
Design Patterns – Builder patterns learning tour
Design Patterns – Agent patterns learning tour
Design Patterns – A learning tour of facade patterns
Design Patterns – A learning tour of decorator patterns
Design Patterns – Enjoy yuan patterns learning journey
Design Patterns – A learning journey of composite patterns
Design Patterns – Adapter patterns learning journey
Design Patterns – Bridge patterns learning journey
Welcome to follow the wechat public account (MarkZoe) to learn from and communicate with each other.