Chain Of Responsibility Design Pattern Example
2014-03-14 16:58
411 查看
Avoid coupling thesender of a request to thereceiver by giving more than one object a chance to handle therequest. Chain thereceiving objects and pass therequest along thechain until an object handles it.
The main intention in Chain Of Responsibility is to decouple theorigin of therequest and thehandling of therequest such that theorigin of therequest need not worry who and how its request is being handled as long as it gets theexpected outcome. By decoupling theorigin of therequest and therequest handler we make sure that both can change easily and new request handlers can be added without theorigin of therequest i.e client being aware of thechanges. In this pattern we create a chain of objects such that each object will have a reference to another object which we call it as successor and these objects are responsible for handling therequest from theclient. All theobjects which are part of thechain are created from classes which confirm to a common interface there by theclient only needs to be aware of theinterface and not necessarily thetypes of its implementations. The client assigns therequest to first object part of thechain and thechain is created in such a way that there would be atleast one object which can handle therequest or theclient would be made aware of thefact that its request couldn’t be handled.
With this brief introduction I would like to put forth a very simple example to illustrate this pattern. In this example we create a chain of file parsers such that depending on theformat of thefile being passed to theparser, theparser has to decide whether its going to parse thefile or pass therequest to its successor parser to take action. The parser we would chain are: Simple text file parser, JSON file parser, CSV file parser and XML file parser. The parsing logic in each of these parser doesn’t parse any file, instead it just prints out a message stating who is handing therequest for which file. We then populate file names of different formats into a list and then iterate through them passing thefile name to thefirst parser in thelist.
Lets define theParser class, first let me show theclass diagram for Parser class:
The Java code for thesame is:
We would now create different handlers for parsing different file formats namely- Simple text file, JSON file, CSV file, XML file and these extend from theParser class and override theparse method. I have kept theimplementation of different parser simple and these methods evaluate if thefile has theformat they are looking for. If a particular handler is unable to process therequest i.e. thefile format is not what it is looking for then theparent method handles such requests. The handler method in theparent class just invokes thesame method on thesuccessor handler.
The simple text parser:
The JSON parser:
The CSV parser:
The XML parser:
Now that we have all thehandlers setup, we need to create a chain of handlers. In this example thechain we create is: TextParser-> JsonParser-> CsvParser-> XmlParser. And if XmlParseris unable to handle therequest then theParser class throws out a message stating that therequest was not handled. Lets see thecode for theclient class which creates a list of files names and then creates thechain which I just described.
In thefile name list above I have intentionally added a file name for which there is no handler created. Running theabove code gives us theoutput:
Happy coding and don’t forget to share!
Reference: Simple example to illustrate Chain Of Responsibility Design Pattern from our JCG partner Mohamed Sanaulla at theExperiences Unlimited blog.
You might also like:
Chain of Responsibility Pattern in Java
Chain of responsibility using Spring @Autowired List
Memento Design Pattern in Java – Example Tutorial
The main intention in Chain Of Responsibility is to decouple theorigin of therequest and thehandling of therequest such that theorigin of therequest need not worry who and how its request is being handled as long as it gets theexpected outcome. By decoupling theorigin of therequest and therequest handler we make sure that both can change easily and new request handlers can be added without theorigin of therequest i.e client being aware of thechanges. In this pattern we create a chain of objects such that each object will have a reference to another object which we call it as successor and these objects are responsible for handling therequest from theclient. All theobjects which are part of thechain are created from classes which confirm to a common interface there by theclient only needs to be aware of theinterface and not necessarily thetypes of its implementations. The client assigns therequest to first object part of thechain and thechain is created in such a way that there would be atleast one object which can handle therequest or theclient would be made aware of thefact that its request couldn’t be handled.
With this brief introduction I would like to put forth a very simple example to illustrate this pattern. In this example we create a chain of file parsers such that depending on theformat of thefile being passed to theparser, theparser has to decide whether its going to parse thefile or pass therequest to its successor parser to take action. The parser we would chain are: Simple text file parser, JSON file parser, CSV file parser and XML file parser. The parsing logic in each of these parser doesn’t parse any file, instead it just prints out a message stating who is handing therequest for which file. We then populate file names of different formats into a list and then iterate through them passing thefile name to thefirst parser in thelist.
Lets define theParser class, first let me show theclass diagram for Parser class:
The Java code for thesame is:
01 | public class Parser { |
02 |
03 | private Parser successor; |
04 |
05 | public void parse(String fileName){ |
06 | if ( getSuccessor() != null ){ |
07 | getSuccessor().parse(fileName); |
08 | } |
09 | else { |
10 | System.out.println( 'Unable tofind thecorrect parserfor thefile: ' +fileName); |
11 | } |
12 | } |
13 |
14 | protected boolean canHandleFile(String fileName, String format){ |
15 | return (fileName == null ) || (fileName.endsWith(format)); |
16 |
17 | } |
18 |
19 | Parser getSuccessor() { |
20 | return successor; |
21 | } |
22 |
23 | void setSuccessor(Parser successor) { |
24 | this .successor = successor; |
25 | } |
26 | } |
The simple text parser:
01 | public class TextParser extends Parser{ |
02 |
03 | public TextParser(Parser successor){ |
04 | this .setSuccessor(successor); |
05 | } |
06 |
07 | @Override |
08 | public void parse(String fileName) { |
09 | if ( canHandleFile(fileName, '.txt' )){ |
10 | System.out.println( 'A text parser is handling thefile: ' +fileName); |
11 | } |
12 | else { |
13 | super .parse(fileName); |
14 | } |
15 |
16 | } |
17 |
18 | } |
01 | public class JsonParser extends Parser { |
02 |
03 | public JsonParser(Parser successor){ |
04 | this .setSuccessor(successor); |
05 | } |
06 |
07 | @Override |
08 | public void parse(String fileName) { |
09 | if ( canHandleFile(fileName, '.json' )){ |
10 | System.out.println( 'A JSON parser is handling thefile: ' +fileName); |
11 | } |
12 | else { |
13 | super .parse(fileName); |
14 | } |
15 |
16 | } |
17 |
18 | } |
01 | public class CsvParser extends Parser { |
02 |
03 | public CsvParser(Parser successor){ |
04 | this .setSuccessor(successor); |
05 | } |
06 |
07 | @Override |
08 | public void parse(String fileName) { |
09 | if ( canHandleFile(fileName, '.csv' )){ |
10 | System.out.println( 'A CSV parser is handling thefile: ' +fileName); |
11 | } |
12 | else { |
13 | super .parse(fileName); |
14 | } |
15 | } |
16 |
17 | } |
01 | public class XmlParser extends Parser { |
02 |
03 | @Override |
04 | public void parse(String fileName) { |
05 | if ( canHandleFile(fileName, '.xml' )){ |
06 | System.out.println( 'A XML parser is handling thefile: ' +fileName); |
07 | } |
08 | else { |
09 | super .parse(fileName); |
10 | } |
11 | } |
12 |
13 | } |
01 | import java.util.List; |
02 | import java.util.ArrayList; |
03 |
04 | public class ChainOfResponsibilityDemo { |
05 |
06 | /** |
07 | * @param args |
08 | */ |
09 | public static void main(String[] args) { |
10 |
11 | //List of file names to parse. |
12 | List<String> fileList =populateFiles(); |
13 |
14 | //No successor for this handler because this is thelast in chain. |
15 | Parser xmlParser = new XmlParser(); |
16 |
17 | //XmlParseris thesuccessor of CsvParser. |
18 | Parser csvParser = new CsvParser(xmlParser); |
19 |
20 | //CsvParseris thesuccessor of JsonParser. |
21 | Parser jsonParser = new JsonParser(csvParser); |
22 |
23 | //JsonParseris thesuccessor of TextParser. |
24 | //TextParseris thestart of thechain. |
25 | Parser textParser = new TextParser(jsonParser); |
26 |
27 | //Pass thefile name to thefirst handler in thechain. |
28 | for ( String fileName : fileList){ |
29 | textParser.parse(fileName); |
30 | } |
31 |
32 | } |
33 |
34 | private static List<String> populateFiles(){ |
35 |
36 | List<String> fileList = new ArrayList<>(); |
37 | fileList.add( 'someFile.txt' ); |
38 | fileList.add( 'otherFile.json' ); |
39 | fileList.add( 'xmlFile.xml' ); |
40 | fileList.add( 'csvFile.csv' ); |
41 | fileList.add( 'csvFile.doc' ); |
42 |
43 | return fileList; |
44 | } |
45 |
46 | } |
1 | A text parser is handling the file : someFile.txt |
2 | A JSON parser is handling the file : otherFile.json |
3 | A XML parser is handling the file : xmlFile.xml |
4 | A CSV parser is handling the file : csvFile.csv |
5 | Unable to find thecorrect parser for the file : csvFile.doc |
Reference: Simple example to illustrate Chain Of Responsibility Design Pattern from our JCG partner Mohamed Sanaulla at theExperiences Unlimited blog.
You might also like:
Chain of Responsibility Pattern in Java
Chain of responsibility using Spring @Autowired List
Memento Design Pattern in Java – Example Tutorial
相关文章推荐
- Design Patterns Uncovered: The Chain Of Responsibility Pattern
- [Design] Chain of Responsibility Pattern
- 设计模式学习—责任链模式(Chain of Responsibility Design Pattern)
- 责任链模式 Chain of Responsibility Pattern
- 设计模式(17)-Chain of Responsibility Pattern
- 如何让孩子爱上设计模式 ——22.责任链模式(Chain of Responsibility Pattern)
- Chain of Responsibility pattern
- java与模式 责任链模式 Chain of Responsibility pattern
- 责任链设计模式(Chain of Responsibility pattern)
- Design Pattern - Behavioral Patterns - Chain of Responsibility Pattern
- 设计模式(17)-Chain of Responsibility Pattern
- Design Patterns -- Chain of Responsibility (CoR)
- Design Pattern Chain of Reponsibility 责任链模式
- 责任链模式(Chain of Responsibility Pattern)
- 设计模式 - Chain of Responsibility Pattern(责任链模式)
- C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】
- 责任链模式【Chain of Responsibility Pattern】
- 我所理解的设计模式(C++实现)——责任链模式(Chain Of Responsibility Pattern)
- C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】
- [重构到模式-Chain of Responsibility Pattern]把哈利波特购书优惠招式重构到责任链模式