When it comes to “design patterns,” many of us have probably heard of them.
But if you had to talk about scenarios, it would be a little “hard to describe.”
With the exception of singleton patterns, which have a lot of application scenarios, you can pick them up at your fingertips, but others can be a little difficult to master. Maybe not at all.
Today, through this article, you can also get handy with the chain of responsibility model.
This article uses examples from real projects to give you an idea of what the chain of responsibility model is.
define
Responsibility chain mode is a design mode. In the chain of responsibility pattern, many objects are connected in a chain by each object’s reference to its next parent. Requests pass along the chain until one of the objects on the chain decides to process the request. The client making the request does not know which object on the chain ultimately handles the request, allowing the system to dynamically reorganize and assign responsibilities without affecting the client.
Chain of responsibility is a software design pattern in object-oriented programming that consists of command objects and a series of processing objects. Each processing object determines which command objects it can process, and it knows how to pass command objects that it cannot process to the next processing object in the chain. The pattern also describes adding new processing objects to the end of the processing chain.
As the name implies, the responsibility chain mode is a chain, there are multiple nodes on the chain, each node has its own responsibility. When there is input, the first responsible node sees if it can process the input, and if so, processes it. If not, pass it on to the next responsible node. And so on, until the last responsible node.
Definitions are always a bit literary, so let’s look at the examples below to understand more.
example
A few examples:
1. Requirements development examples
Let’s say there’s a demand coming in, and the intern gets the demand first.
If interns can make it happen, make it happen. If not, he passes the requirement on to the junior engineer.
If junior engineers can do it, do it. If not, hand it over to intermediate engineers.
If intermediate engineers can implement it, implement it directly. If not, hand it over to senior engineers.
If senior engineers can do it, just do it. If not, take it to the CTO.
If cTOS can be implemented, implement them directly. If not, tell the product directly, demand does not do.
For programmers, there are no requirements that can’t be implemented, only requirements that they don’t want to do
2. Buy a basket
Suppose you have a basketball and want to buy a basket.
You must have gone to the store and asked the owner to bring out the baskets of all sizes.
Then you try them one by one.
Not the first one, just the second one.
Not the second one, just the third one.
.
Until I find the right one.
You should be somewhat familiar with the chain of responsibility model by definition and examples.
Do you feel familiar with the code you write?
Don’t worry, let’s take a look at some familiar code, using Java code as an example, and other languages as well.
scenario
Given an input value, perform different logic depending on the input value.
Let’s take a look and write the following code in minutes:
String input = "1";
if ("1".equals(input)) {
//TODO do something
} else if ("2".equals(input)) {
//TODO do something
} else if ("3".equals(input)) {
//TODO do something
}
Copy the code
Or something like this:
String input = "1";
switch (input) {
case "1":
//TODO do something
break;
case "2":
//TODO do something
break;
case "3":
//TODO do something
break;
default:
//TODO do something
break;
}
Copy the code
If the logic in each branch is simple, that’s fine, but if the logic is complex, ** assume that each case takes about 100 lines of code to process, and there are 10 cases, all of a sudden a “thousand lines of code” file. ** It’s also bad for maintenance, testing, and extension.
If we can find a way to split the code into one file per case, not only the code logic is much clearer, but also the subsequent maintenance, expansion and testing are much more convenient.
That’s where the core of this article, the chain of responsibility model, comes in: split code.
Chain of responsibility pattern split code
Here to the above scenario as an example of the split code, I believe you can draw inferences from other scenarios.
Define an abstract class.
Public abstract class BaseCase {// istrueShow that you can handle itcaseprivate boolean isConsume; public BaseCase(boolean isConsume) { this.isConsume = isConsume; } private BaseCase nextCase; public voidsetNextCase(BaseCase nextCase) {
this.nextCase = nextCase;
}
public void handleRequest() {
if(isConsume) {// If the current node can process, process directlydoSomething();
} else{// If the current node cannot process, and there is a next node, the next node to processif(null ! = nextCase) { nextCase.handleRequest(); } } } abstract protected voiddoSomething();
}
Copy the code
The comments are already made clear. I will not repeat it here.
2. Each case to implement the abstract class.
Here’s one case, the rest you can look at the code.
public class OneCase extends BaseCase {
public OneCase(boolean isConsume) {
super(isConsume);
}
@Override protected void doSomething() {
// TODO dosomething System.out.println(getClass().getName()); }}Copy the code
3. Initialize each case and specify the next node of each case.
String input = "1";
OneCase oneCase = new OneCase("1".equals(input));
TwoCase twoCase = new TwoCase("2".equals(input));
DefaultCase defaultCase = new DefaultCase(true);
oneCase.setNextCase(twoCase);
twoCase.setNextCase(defaultCase);
oneCase.handleRequest();
Copy the code
Well, that’s the end of the chain of responsibility split code.
An optimized
The above is a basic implementation of the chain of responsibility pattern split code.
The OkHttp Interceptor implementation is available only when Interceptor is Interceptor.
So I looked over here and made the following improvements.
Let’s talk about the general idea first.
Gather all the cases together and iterate to determine which cases can be processed.
The above scenario is also used as an example.
1. Define an interface.
Interface BaseCase {// allcaseThe method that handles the logic is voiddoSomething(String input, BaseCase baseCase);
}
Copy the code
2. Establish a responsibility chain management class to manage all cases.
Public class CaseChain implements BaseCase {// AllcasePrivate List<BaseCase> mCaseList = new ArrayList<>(); // index, used to iterate over allcasePrivate int index = 0; / / addcase
public CaseChain addBaseCase(BaseCase baseCase) {
mCaseList.add(baseCase);
return this;
}
@Override public void doSomething(String input, BaseCase BaseCase) {// Return Something(String input, BaseCase BaseCase)if (index == mCaseList.size()) return; // Get the currentcaseBaseCase currentCase = mCaseList.get(index); // change the index value so that the next callback retrieves the next node to traversal index++; // call currentcaseCurrentcase.dosomething (input, this); }}Copy the code
3. Implementation interface of each case. Here’s an example of one.
public class OneCase implements BaseCase {
@Override
public void doSomething(String input, BaseCase baseCase) {
if ("1".equals(input)) {
// TODO do something
System.out.println(getClass().getName());
return; BaseCase (input, baseCase); baseCase (input, baseCase); }}Copy the code
4. Initialize each case
String input = "1";
CaseChain caseChain = new CaseChain();
caseChain.addBaseCase(new OneCase())
.addBaseCase(new TwoCase())
.addBaseCase(new DefaultCase());
caseChain.doSomething(input, caseChain);
Copy the code
Well, the notes are very clear, I believe you understand is no problem.
So that’s the end of our chain of responsibility model.
You know the chain of responsibility model by heart.
If you have any questions
You can leave a message, look at the code or tap the code.
conclusion
This article describes the power of the chain of responsibility model using a real project scenario as an example.
After reading the article, you may only learn its form, but not its god.
Through continuous use and the accumulation of their own experience, I believe that it is also a matter of time to achieve both shape and spirit.
Once you get it, it’s no longer “I’m going to use the chain of responsibility model, so I wrote the code.”
It’s “I wrote the code and realized I was using the chain of responsibility model.”
Just as in “heaven and Dragon” in Zhang Sanfeng taught Zhang Wuji taiji sword, finally Zhang Wuji forgot all the same.
Tips:
Learning the new design mode, it is inevitable that a little itching.
But don’t abuse design patterns.
Don’t design for design’s sake.
Let’s say you have a few cases, and the processing logic is a box.
You said you were going to use design patterns? It costs more, but it doesn’t have to.
So learning it is one thing, and when to use it is another.
Feel good, welcome to share.
All code in this article
Reference:
www.runoob.com/design-patt…
Github.com/simple-andr…
www.jianshu.com/p/8a157cb73…