|
9 | 9 | ---
|
10 | 10 |
|
11 | 11 | ##Intent
|
12 |
| -Balking Pattern is used to prevent an object from executing certain code if it is an |
13 |
| -incomplete or inappropriate state |
| 12 | + |
| 13 | +Balking Pattern is used to prevent an object from executing a certain code if it is in an incomplete |
| 14 | +or inappropriate state. |
| 15 | + |
| 16 | +##Explanation |
| 17 | + |
| 18 | +Real world example |
| 19 | + |
| 20 | +>There's a start-button in a washing machine to initiate the laundry washing. When the washing |
| 21 | +>machine is inactive the button works as expected, but if it's already washing the button does |
| 22 | +>nothing. |
| 23 | +
|
| 24 | +In plain words |
| 25 | + |
| 26 | +>Using the balking pattern, a certain code executes only if the object is in particular state. |
| 27 | +
|
| 28 | +Wikipedia says |
| 29 | + |
| 30 | +>The balking pattern is a software design pattern that only executes an action on an object when |
| 31 | +>the object is in a particular state. For example, if an object reads ZIP files and a calling |
| 32 | +>method invokes a get method on the object when the ZIP file is not open, the object would "balk" |
| 33 | +>at the request. |
| 34 | +
|
| 35 | +**Programmatic Example** |
| 36 | + |
| 37 | +In this example implementation,`WashingMachine` is an object that has two states in which it can |
| 38 | +be: ENABLED and WASHING. If the machine is ENABLED, the state changes to WASHING using a thread-safe |
| 39 | +method. On the other hand, if it already has been washing and any other thread executes`wash()` |
| 40 | +it won't do that and returns without doing anything. |
| 41 | + |
| 42 | +Here are the relevant parts of the`WashingMachine` class. |
| 43 | + |
| 44 | +```java |
| 45 | +@Slf4j |
| 46 | +publicclassWashingMachine { |
| 47 | + |
| 48 | +privatefinalDelayProvider delayProvider; |
| 49 | +privateWashingMachineState washingMachineState; |
| 50 | + |
| 51 | +publicWashingMachine(DelayProviderdelayProvider) { |
| 52 | +this.delayProvider= delayProvider; |
| 53 | +this.washingMachineState=WashingMachineState.ENABLED; |
| 54 | + } |
| 55 | + |
| 56 | +publicWashingMachineStategetWashingMachineState() { |
| 57 | +return washingMachineState; |
| 58 | + } |
| 59 | + |
| 60 | +publicvoidwash() { |
| 61 | +synchronized (this) { |
| 62 | +var machineState= getWashingMachineState(); |
| 63 | +LOGGER.info("{}: Actual machine state: {}",Thread.currentThread().getName(), machineState); |
| 64 | +if (this.washingMachineState==WashingMachineState.WASHING) { |
| 65 | +LOGGER.error("Cannot wash if the machine has been already washing!"); |
| 66 | +return; |
| 67 | + } |
| 68 | +this.washingMachineState=WashingMachineState.WASHING; |
| 69 | + } |
| 70 | +LOGGER.info("{}: Doing the washing",Thread.currentThread().getName()); |
| 71 | +this.delayProvider.executeAfterDelay(50,TimeUnit.MILLISECONDS,this::endOfWashing); |
| 72 | + } |
| 73 | + |
| 74 | +publicsynchronizedvoidendOfWashing() { |
| 75 | + washingMachineState=WashingMachineState.ENABLED; |
| 76 | +LOGGER.info("{}: Washing completed.",Thread.currentThread().getId()); |
| 77 | + } |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +Here's the simple`DelayProvider` interface used by the`WashingMachine`. |
| 82 | + |
| 83 | +```java |
| 84 | +publicinterfaceDelayProvider { |
| 85 | +voidexecuteAfterDelay(longinterval,TimeUnittimeUnit,Runnabletask); |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +Now we introduce the application using the`WashingMachine`. |
| 90 | + |
| 91 | +```java |
| 92 | +publicstaticvoid main(String... args) { |
| 93 | +finalvar washingMachine=newWashingMachine(); |
| 94 | +var executorService=Executors.newFixedThreadPool(3); |
| 95 | +for (int i=0; i<3; i++) { |
| 96 | + executorService.execute(washingMachine::wash); |
| 97 | + } |
| 98 | + executorService.shutdown(); |
| 99 | +try { |
| 100 | + executorService.awaitTermination(10,TimeUnit.SECONDS); |
| 101 | + }catch (InterruptedException ie) { |
| 102 | +LOGGER.error("ERROR: Waiting on executor service shutdown!"); |
| 103 | +Thread.currentThread().interrupt(); |
| 104 | + } |
| 105 | + } |
| 106 | +``` |
| 107 | + |
| 108 | +Here is the console output of the program. |
| 109 | + |
| 110 | +``` |
| 111 | +14:02:52.268 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-2: Actual machine state: ENABLED |
| 112 | +14:02:52.272 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-2: Doing the washing |
| 113 | +14:02:52.272 [pool-1-thread-3] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-3: Actual machine state: WASHING |
| 114 | +14:02:52.273 [pool-1-thread-3] ERROR com.iluwatar.balking.WashingMachine - Cannot wash if the machine has been already washing! |
| 115 | +14:02:52.273 [pool-1-thread-1] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-1: Actual machine state: WASHING |
| 116 | +14:02:52.273 [pool-1-thread-1] ERROR com.iluwatar.balking.WashingMachine - Cannot wash if the machine has been already washing! |
| 117 | +14:02:52.324 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - 14: Washing completed. |
| 118 | +``` |
14 | 119 |
|
15 | 120 | ##Class diagram
|
| 121 | + |
16 | 122 | 
|
17 | 123 |
|
18 | 124 | ##Applicability
|
| 125 | + |
19 | 126 | Use the Balking pattern when
|
20 | 127 |
|
21 |
| -*you want to invoke an action on an object only when it is in a particular state |
22 |
| -*objects are generally only in a state that is prone to balking temporarily |
23 |
| -but for an unknown amount of time |
| 128 | +*You want to invoke an action on an object only when it is in a particular state |
| 129 | +*Objects are generally only in a state that is prone to balking temporarily but for an unknown |
| 130 | + amount of time |
24 | 131 |
|
25 | 132 | ##Related patterns
|
26 |
| -* Guarded Suspension Pattern |
27 |
| -* Double Checked Locking Pattern |
| 133 | + |
| 134 | +*[Guarded Suspension Pattern](https://java-design-patterns.com/patterns/guarded-suspension/) |
| 135 | +*[Double Checked Locking Pattern](https://java-design-patterns.com/patterns/double-checked-locking/) |
| 136 | + |
| 137 | +##Credits |
| 138 | + |
| 139 | +*[Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML, 2nd Edition, Volume 1](https://www.amazon.com/gp/product/0471227293/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0471227293&linkId=0e39a59ffaab93fb476036fecb637b99) |