1 //---------------------------------------------------------------------- 2 // 3 // PerfectJPattern: "Design patterns are good but components are better!" 4 // IHandler.java Copyright (c) 2009 Giovanni Azua Garcia 5 // bravegag@hotmail.com 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; either version 3 10 // of the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, see <http://www.gnu.org/licenses/>. 19 // 20 //---------------------------------------------------------------------- 21 package org.perfectjpattern.core.api.behavioral.chainofresponsibility; 22 23 /** 24 * <b>Chain of Responsibility Design Pattern</b>: Avoid coupling the sender of 25 * a request to its receiver by giving more than one object a chance to handle 26 * the request. Chain the receiving objects and pass the request along the chain 27 * until an object handles it. (Gamma et al, Design Patterns)<br/> 28 * <br/> 29 * 30 * <b>Responsibility</b>: Abstract definition of the "Handler". 31 * 32 * <ul> 33 * <li>Defines an interface for handling requests.</li> 34 * <li>Implements the Successor link.</li> 35 * </ul> 36 * 37 * <br/> 38 * Example usage: 39 * <pre><code> 40 * // 41 * // Create chain elements 42 * // 43 * IHandler myFirst = new ConcreteHandler(); 44 * IHandler mySecond = new ConcreteHandler(); 45 * IHandler myThird = new ConcreteHandler(); 46 * 47 * // 48 * // Associate Handler elements 49 * // 50 * myFirst.setSuccessor(mySecond); 51 * mySecond.setSuccessor(myThird); 52 * 53 * // 54 * // Execute the first Handler that triggers the execution of the 55 * // complete chain. 56 * // 57 * myFirst.start(NullRequest.getInstance()); 58 * </code></pre> 59 * 60 * @param <R> Request parameter type 61 * 62 * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a> 63 * @version $Revision: 1.0 $ $Date: Jun 23, 2007 1:27:25 PM $ 64 */ 65 public 66 interface IHandler<R> 67 { 68 //------------------------------------------------------------------------ 69 // public 70 //------------------------------------------------------------------------ 71 /** 72 * Returns true if this <code>IHandler</code> can handle the given request, 73 * false otherwise. 74 * 75 * @param aRequest Context-specific request to handle. 76 * @return true if this <code>IHandler</code> can handle the given request, 77 * false otherwise. 78 * @throws IllegalArgumentException 'aRequest' must not be null. 79 */ 80 public boolean 81 canHandle(R aRequest) 82 throws IllegalArgumentException; 83 84 //------------------------------------------------------------------------ 85 /** 86 * Triggers execution of the Chain if the target Handler is the first 87 * reference, otherwise implements the decision-making regarding forwarding 88 * the request to its successor <code>IHandler</code> instance. 89 * 90 * @param aRequest Context-specific request to handle. 91 * @throws IllegalArgumentException 'aRequest' must not be null. 92 */ 93 public void 94 start(R aRequest) 95 throws IllegalArgumentException; 96 97 //------------------------------------------------------------------------ 98 /** 99 * Handle the given request. Implements the actual handling logic and must 100 * not contain any decision-making regarding e.g. forwarding the request. 101 * 102 * @param aRequest Context-specific request to handle. 103 * @throws IllegalArgumentException 'aRequest' must not be null. 104 * @throws IllegalArgumentException 'aRequest' can not be handled. 105 */ 106 public void 107 handle(R aRequest) 108 throws IllegalArgumentException; 109 110 //------------------------------------------------------------------------ 111 /** 112 * Returns the Successor handler. 113 * 114 * @return Successor handler. 115 */ 116 public IHandler<R> 117 getSuccessor(); 118 119 //------------------------------------------------------------------------ 120 /** 121 * Sets the Successor element. 122 * 123 * @param aSuccessor Successor handler 124 * @throws IllegalArgumentException 'aSuccessor' must not be null. 125 */ 126 public void 127 setSuccessor(IHandler<R> aSuccessor) 128 throws IllegalArgumentException; 129 130 //------------------------------------------------------------------------ 131 /** 132 * Set the <code>IChainStrategy</code> to this <code>IHandler</code>. 133 * <code>IChainStrategy</code> allows to easily modify how the 134 * Chain should behave. Possible implementations are e.g. 135 * <ul> 136 * <li>Halt as soon as the first Handler processes the request</li> 137 * <li>Let all handlers process the request</li> 138 * <li>Let the first N handlers process the request</li> 139 * </ul> 140 * 141 * @param aStrategy Continuation strategy defines how the chain should 142 * behave 143 * @throws IllegalArgumentException 'aStrategy' must not be null. 144 */ 145 public void 146 setChainStrategy(IChainStrategy aStrategy) 147 throws IllegalArgumentException; 148 }