This is the sixth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

The delegation pattern, which is not one of the GOF23 common patterns, allows object composition to achieve the same code reuse as inheritance.

A, definitions,

Delegation is a way to make composition as reusable as inheritance. In a delegate, handling a request involves two objects: the receiving object delegates the action to its delegate object, which is similar to deferring the request to a subclass of its parent class.

The delegate pattern is similar to the proxy pattern in that it can be thought of as a special case of full proxy for static agents. There are essential differences between the two patterns: the agent pattern focuses on process, while the delegate pattern focuses on results.

The difference between the two is very abstract, to be specific:

  • The delegating mode generally works like this: you call me, I act as a middleman, I don’t do anything, and I go to someone else to deal with your needs/orders. This emphasizes a process of weighing options.
  • The general process of the agency mode is as follows: if you want to do something, you can clearly find A to complete it, but you don’t go to A, you go to A’s agent to deal with it. In fact, A’s agent still goes to A to deal with it.

The basic function of delegate mode is to be responsible for the invocation and assignment of tasks. In the Java ecosystem, the Spring framework makes use of the delegate pattern, which is known as dispatcherServlets. Delegating: Delegating: Delegating: Delegating: Delegating: Delegating: Delegating: Delegating

Two, code implementation

Here imagine a dry engineering company, there are Boss, Manager, Worker and other roles in the company, the Worker specifically subdivided electrician ElectWorker, WoodWorker and so on.

In one scenario, the boss sends a command to the manager to arrange the electrician or carpenter’s work.

The first step is to create an abstract interface for the worker that describes the nature of the worker’s work and the operations that the worker performs.

Public interface Worker {/** * workType * @return workType */ String workType(); Void doingJob(String command); void doingJob(String command); }Copy the code

Then implement carpentry and electrician.

Public class implements Worker{/** * implements Worker ** @override public String workType() {return  "WoodWorker"; } /** * @override public void doingJob(String command) {system.out.println (" I am WoodWorker,receive ") Command 【 "+ command + "】,start to work"); }} public class ElectWorker implements Worker{/** * @return */ @override public String workType() { return "ElectWorker"; */ @override public void doingJob(String command) {system.out.println (" I am ElectWorker,receive ") Command 【 "+ command + "】,start to work"); }}Copy the code

The immediate supervisor of the workers is the manager.

public class Manager { final Map<String,Worker> scheduler = new HashMap<>(); public Manager(){ scheduler.put(WorkType.WOOD,new WoodWorker()); scheduler.put(WorkType.ELECT,new ElectWorker()); } public void doing(String command){ scheduler.get(ANALYSIS_WORK_TYPE.apply(command)).doingJob(command); Static final Function<String,String> ANALYSIS_WORK_TYPE = command->{ if(command.contains(WorkType.WOOD)){ return WorkType.WOOD; }else if(command.contains(WorkType.ELECT)){ return WorkType.ELECT; } throw new UnsupportedOperationException(); }; interface WorkType{ String WOOD = "Wood"; String ELECT = "Elect"; }}Copy the code

The manager manages workers and schedules tasks through scheduler. Instead of being the final executor of commands/tasks, he will analyze specific task types according to commands and then arrange specific workers to do the work.

Of course, it is the boss who manages the manager. The boss just needs to give orders to the manager without knowing who is going to perform the task.

public class Boss { public void command(String command,Manager manager){ manager.doing(command); }}Copy the code

Execute the process.

public class DelegatingApp { public static void main(String[] args) { new Boss().command("anybody Wood",new Manager()); new Boss().command("anybody Elect",new Manager()); }}Copy the code

Output after execution.

The entire program UML class diagram is shown below

Third, summary

In general, with the delegate pattern, there is a clearer logical hierarchy, a clearer delineation of responsibilities for each role, and a much more elegant code implementation. But it’s also important to distinguish between the agent, delegate, and policy patterns.