Merge branch 'master' into converter
This commit is contained in:
27
balking/README.md
Normal file
27
balking/README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
layout: pattern
|
||||||
|
title: Balking
|
||||||
|
folder: balking
|
||||||
|
permalink: /patterns/balking/
|
||||||
|
categories: Concurrency
|
||||||
|
tags:
|
||||||
|
- Java
|
||||||
|
- Difficulty-Beginner
|
||||||
|
---
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
Balking Pattern is used to prevent an object from executing certain code if it is an
|
||||||
|
incomplete or inappropriate state
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Applicability
|
||||||
|
Use the Balking pattern when
|
||||||
|
|
||||||
|
*you want to invoke an action on an object only when it is in a particular state
|
||||||
|
*objects are generally only in a state that is prone to balking temporarily
|
||||||
|
but for an unknown amount of time
|
||||||
|
|
||||||
|
## Related patterns
|
||||||
|
* Guarded Suspendion Pattern
|
||||||
|
* Double Checked Locking Pattern
|
BIN
balking/etc/balking.png
Normal file
BIN
balking/etc/balking.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
46
balking/etc/balking.ucls
Normal file
46
balking/etc/balking.ucls
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<class-diagram version="1.1.13" icons="true" automaticImage="PNG" always-add-relationships="false"
|
||||||
|
generalizations="true" realizations="true" associations="true" dependencies="false" nesting-relationships="true"
|
||||||
|
router="FAN">
|
||||||
|
<class id="1" language="java" name="com.iluwatar.balking.App" project="balking"
|
||||||
|
file="/balking/src/main/java/com/iluwatar/balking/App.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
|
<position height="113" width="114" x="135" y="103"/>
|
||||||
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
|
sort-features="false" accessors="true" visibility="true">
|
||||||
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
</display>
|
||||||
|
</class>
|
||||||
|
<class id="2" language="java" name="com.iluwatar.balking.WashingMachine" project="balking"
|
||||||
|
file="/balking/src/main/java/com/iluwatar/balking/WashingMachine.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
|
<position height="149" width="268" x="289" y="103"/>
|
||||||
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
|
sort-features="false" accessors="true" visibility="true">
|
||||||
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
</display>
|
||||||
|
</class>
|
||||||
|
<enumeration id="3" language="java" name="com.iluwatar.balking.WashingMachineState" project="balking"
|
||||||
|
file="/balking/src/main/java/com/iluwatar/balking/WashingMachineState.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
|
<position height="113" width="192" x="289" y="292"/>
|
||||||
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
|
sort-features="false" accessors="true" visibility="true">
|
||||||
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
</display>
|
||||||
|
</enumeration>
|
||||||
|
<association id="4">
|
||||||
|
<end type="SOURCE" refId="2" navigable="false">
|
||||||
|
<attribute id="5" name="washingMachineState"/>
|
||||||
|
<multiplicity id="6" minimum="0" maximum="1"/>
|
||||||
|
</end>
|
||||||
|
<end type="TARGET" refId="3" navigable="true"/>
|
||||||
|
<display labels="true" multiplicity="true"/>
|
||||||
|
</association>
|
||||||
|
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
|
sort-features="false" accessors="true" visibility="true">
|
||||||
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
</classifier-display>
|
||||||
|
<association-display labels="true" multiplicity="true"/>
|
||||||
|
</class-diagram>
|
24
balking/etc/balking.urm.puml
Normal file
24
balking/etc/balking.urm.puml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.balking {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class WashingMachine {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- washingMachineState : WashingMachineState
|
||||||
|
+ WashingMachine()
|
||||||
|
+ endOfWashing()
|
||||||
|
+ getWashingMachineState() : WashingMachineState
|
||||||
|
+ wash()
|
||||||
|
}
|
||||||
|
enum WashingMachineState {
|
||||||
|
+ ENABLED {static}
|
||||||
|
+ WASHING {static}
|
||||||
|
+ valueOf(name : String) : WashingMachineState {static}
|
||||||
|
+ values() : WashingMachineState[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WashingMachine --> "-washingMachineState" WashingMachineState
|
||||||
|
@enduml
|
46
balking/pom.xml
Normal file
46
balking/pom.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License
|
||||||
|
Copyright (c) 2014 Ilkka Seppälä
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<version>1.15.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>balking</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
65
balking/src/main/java/com/iluwatar/balking/App.java
Normal file
65
balking/src/main/java/com/iluwatar/balking/App.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* The MIT License
|
||||||
|
* Copyright (c) 2014 Ilkka Seppälä
|
||||||
|
* <p>
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
* <p>
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
* <p>
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In Balking Design Pattern if an object’s method is invoked when it is in an inappropriate state,
|
||||||
|
* then the method will return without doing anything. Objects that use this pattern are generally only in a
|
||||||
|
* state that is prone to balking temporarily but for an unknown amount of time
|
||||||
|
*
|
||||||
|
* In this example implementation WashingMachine is an object that has two states
|
||||||
|
* in which it can be: ENABLED and WASHING. If the machine is ENABLED
|
||||||
|
* the state is changed into WASHING that any other thread can't invoke this action on this and then do the job.
|
||||||
|
* On the other hand if it have been already washing and any other thread execute wash()
|
||||||
|
* it can't do that once again and returns doing nothing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments - not used
|
||||||
|
*/
|
||||||
|
public static void main(String... args) {
|
||||||
|
final WashingMachine washingMachine = new WashingMachine();
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
executorService.execute(washingMachine::wash);
|
||||||
|
}
|
||||||
|
executorService.shutdown();
|
||||||
|
try {
|
||||||
|
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
LOGGER.error("ERROR: Waiting on executor service shutdown!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* The MIT License
|
||||||
|
* Copyright (c) 2014 Ilkka Seppälä
|
||||||
|
* <p>
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
* <p>
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
* <p>
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class WashingMachine {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
|
||||||
|
|
||||||
|
private WashingMachineState washingMachineState;
|
||||||
|
|
||||||
|
public WashingMachine() {
|
||||||
|
washingMachineState = WashingMachineState.ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WashingMachineState getWashingMachineState() {
|
||||||
|
return washingMachineState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method responsible for washing
|
||||||
|
* if the object is in appropriate state
|
||||||
|
*/
|
||||||
|
public void wash() {
|
||||||
|
synchronized (this) {
|
||||||
|
LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), getWashingMachineState());
|
||||||
|
if (washingMachineState == WashingMachineState.WASHING) {
|
||||||
|
LOGGER.error("ERROR: Cannot wash if the machine has been already washing!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
washingMachineState = WashingMachineState.WASHING;
|
||||||
|
}
|
||||||
|
LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());
|
||||||
|
try {
|
||||||
|
Thread.sleep(50);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
ie.printStackTrace();
|
||||||
|
}
|
||||||
|
endOfWashing();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method responsible of ending the washing
|
||||||
|
* by changing machine state
|
||||||
|
*/
|
||||||
|
public synchronized void endOfWashing() {
|
||||||
|
washingMachineState = WashingMachineState.ENABLED;
|
||||||
|
LOGGER.info("{}: Washing completed.", Thread.currentThread().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* The MIT License
|
||||||
|
* Copyright (c) 2014 Ilkka Seppälä
|
||||||
|
* <p>
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
* <p>
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
* <p>
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WashingMachineState enum describes in which state machine is,
|
||||||
|
* it can be enabled and ready to work as well as during washing
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum WashingMachineState {
|
||||||
|
ENABLED, WASHING
|
||||||
|
}
|
39
balking/src/test/java/com/iluwatar/balking/AppTest.java
Normal file
39
balking/src/test/java/com/iluwatar/balking/AppTest.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* The MIT License
|
||||||
|
* Copyright (c) 2014 Ilkka Seppälä
|
||||||
|
* <p>
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
* <p>
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
* <p>
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application test
|
||||||
|
*/
|
||||||
|
public class AppTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void main() throws Exception {
|
||||||
|
String[] args = {};
|
||||||
|
App.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* The MIT License
|
||||||
|
* Copyright (c) 2014 Ilkka Seppälä
|
||||||
|
* <p>
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
* <p>
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
* <p>
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class WashingMachineTest {
|
||||||
|
|
||||||
|
private volatile WashingMachineState machineStateGlobal;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wash() throws Exception {
|
||||||
|
WashingMachine washingMachine = new WashingMachine();
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
executorService.execute(washingMachine::wash);
|
||||||
|
executorService.execute(() -> {
|
||||||
|
washingMachine.wash();
|
||||||
|
machineStateGlobal = washingMachine.getWashingMachineState();
|
||||||
|
});
|
||||||
|
executorService.shutdown();
|
||||||
|
try {
|
||||||
|
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
ie.printStackTrace();
|
||||||
|
}
|
||||||
|
assertEquals(WashingMachineState.WASHING, machineStateGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void endOfWashing() throws Exception {
|
||||||
|
WashingMachine washingMachine = new WashingMachine();
|
||||||
|
washingMachine.wash();
|
||||||
|
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,11 +12,12 @@ tags:
|
|||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
The Event-based Asynchronous Pattern makes available the advantages of multithreaded applications while hiding many
|
The Event-based Asynchronous Pattern makes available the advantages of multithreaded applications while hiding many
|
||||||
of the complex issues inherent in multithreaded design. Using a class that supports this pattern can allow you to:-
|
of the complex issues inherent in multithreaded design. Using a class that supports this pattern can allow you to:
|
||||||
(1) Perform time-consuming tasks, such as downloads and database operations, "in the background," without interrupting your application.
|
|
||||||
(2) Execute multiple operations simultaneously, receiving notifications when each completes.
|
1. Perform time-consuming tasks, such as downloads and database operations, "in the background," without interrupting your application.
|
||||||
(3) Wait for resources to become available without stopping ("hanging") your application.
|
2. Execute multiple operations simultaneously, receiving notifications when each completes.
|
||||||
(4) Communicate with pending asynchronous operations using the familiar events-and-delegates model.
|
3. Wait for resources to become available without stopping ("hanging") your application.
|
||||||
|
4. Communicate with pending asynchronous operations using the familiar events-and-delegates model.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ layout: pattern
|
|||||||
title: Guarded Suspension
|
title: Guarded Suspension
|
||||||
folder: guarded-suspension
|
folder: guarded-suspension
|
||||||
permalink: /patterns/guarded-suspension/
|
permalink: /patterns/guarded-suspension/
|
||||||
|
pumlid: ROux3W8n30LxJW47IDnJxLLCOcMD4YVoXxq-eQTwev56UeSvgiVejmTBwL4fjDzFzsLF0CKhD_OpNc6aPOgJU2vp0FUuSAVmnW-cIiPDqa9tKZ4OQ1kW1MgbcYniaHXF0VBoH-VGaTVlnK5Iztu1
|
||||||
categories: Concurrency
|
categories: Concurrency
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
@startuml
|
@startuml
|
||||||
package com.iluwatar.guarded.suspension {
|
package com.iluwatar.guarded.suspension {
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
class GuardedQueue {
|
class GuardedQueue {
|
||||||
- LOGGER : Logger {static}
|
- LOGGER : Logger {static}
|
||||||
- sourceList : Queue<Integer>
|
- sourceList : Queue<Integer>
|
||||||
|
@ -4,6 +4,7 @@ title: Hexagonal Architecture
|
|||||||
folder: hexagonal
|
folder: hexagonal
|
||||||
permalink: /patterns/hexagonal/
|
permalink: /patterns/hexagonal/
|
||||||
pumlid: HSTB4W8X30N0g-W1XkozpPD90LO8L3wEnzUTk-xxq2fvSfhSUiJs1v7XAcr4psSwMrqQh57gcZGaBmICNdZZEDb7qsCZWasT9lm7wln1MmeXZlfVIPjbvvGl
|
pumlid: HSTB4W8X30N0g-W1XkozpPD90LO8L3wEnzUTk-xxq2fvSfhSUiJs1v7XAcr4psSwMrqQh57gcZGaBmICNdZZEDb7qsCZWasT9lm7wln1MmeXZlfVIPjbvvGl
|
||||||
|
pumlformat: svg
|
||||||
categories: Architectural
|
categories: Architectural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@startuml
|
@startuml
|
||||||
|
left to right direction
|
||||||
package com.iluwatar.intercepting.filter {
|
package com.iluwatar.intercepting.filter {
|
||||||
abstract class AbstractFilter {
|
abstract class AbstractFilter {
|
||||||
- next : Filter
|
- next : Filter
|
||||||
@ -79,10 +80,10 @@ AbstractFilter --> "-next" Filter
|
|||||||
DListener --+ Target
|
DListener --+ Target
|
||||||
FilterChain --> "-chain" Filter
|
FilterChain --> "-chain" Filter
|
||||||
FilterManager --> "-filterChain" FilterChain
|
FilterManager --> "-filterChain" FilterChain
|
||||||
AbstractFilter ..|> Filter
|
AbstractFilter ..|> Filter
|
||||||
AddressFilter --|> AbstractFilter
|
AddressFilter --|> AbstractFilter
|
||||||
ContactFilter --|> AbstractFilter
|
ContactFilter --|> AbstractFilter
|
||||||
DepositFilter --|> AbstractFilter
|
DepositFilter --|> AbstractFilter
|
||||||
NameFilter --|> AbstractFilter
|
NameFilter --|> AbstractFilter
|
||||||
OrderFilter --|> AbstractFilter
|
OrderFilter --|> AbstractFilter
|
||||||
@enduml
|
@enduml
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@startuml
|
@startuml
|
||||||
|
left to right direction
|
||||||
package com.iluwatar.interpreter {
|
package com.iluwatar.interpreter {
|
||||||
class App {
|
class App {
|
||||||
- LOGGER : Logger {static}
|
- LOGGER : Logger {static}
|
||||||
@ -44,8 +45,8 @@ package com.iluwatar.interpreter {
|
|||||||
MultiplyExpression --> "-leftExpression" Expression
|
MultiplyExpression --> "-leftExpression" Expression
|
||||||
MinusExpression --> "-leftExpression" Expression
|
MinusExpression --> "-leftExpression" Expression
|
||||||
PlusExpression --> "-leftExpression" Expression
|
PlusExpression --> "-leftExpression" Expression
|
||||||
MinusExpression --|> Expression
|
MinusExpression --|> Expression
|
||||||
MultiplyExpression --|> Expression
|
MultiplyExpression --|> Expression
|
||||||
NumberExpression --|> Expression
|
NumberExpression --|> Expression
|
||||||
PlusExpression --|> Expression
|
PlusExpression --|> Expression
|
||||||
@enduml
|
@enduml
|
||||||
|
@ -4,6 +4,7 @@ title: Layers
|
|||||||
folder: layers
|
folder: layers
|
||||||
permalink: /patterns/layers/
|
permalink: /patterns/layers/
|
||||||
pumlid: BSR13OCm30NGLSe0n7UsCS62L8w9x6yGszD3t-bDpQhc9kdwEO0H2v7pNVQ68zSCyNeQn53gsQbftWns-lB5yoRHTfi70-8Mr3b-8UL7F4XG_otflOpi-W80
|
pumlid: BSR13OCm30NGLSe0n7UsCS62L8w9x6yGszD3t-bDpQhc9kdwEO0H2v7pNVQ68zSCyNeQn53gsQbftWns-lB5yoRHTfi70-8Mr3b-8UL7F4XG_otflOpi-W80
|
||||||
|
pumlformat: svg
|
||||||
categories: Architectural
|
categories: Architectural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
|
@ -3,9 +3,8 @@ layout: pattern
|
|||||||
title: Message Channel
|
title: Message Channel
|
||||||
folder: message-channel
|
folder: message-channel
|
||||||
permalink: /patterns/message-channel/
|
permalink: /patterns/message-channel/
|
||||||
pumlid: NSZB3SCm203GLTe1RExTXX1akm9YyMdMRy-zFRtdCf8wkLmUCtF72y3nxcFbhAE2dIvBjknqAIof6nCTtlZ1TdAiOMrZ9hi5ACOFe1o1WnjDD6C1Jlg_NgvzbyeN
|
|
||||||
categories: Integration
|
categories: Integration
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
- EIP
|
- EIP
|
||||||
- Apache Camel™
|
- Apache Camel™
|
||||||
@ -24,4 +23,4 @@ Use the Message Channel pattern when
|
|||||||
|
|
||||||
## Real world examples
|
## Real world examples
|
||||||
|
|
||||||
* [akka-camel](http://doc.akka.io/docs/akka/snapshot/scala/camel.html)
|
* [akka-camel](http://doc.akka.io/docs/akka/snapshot/scala/camel.html)
|
||||||
|
@ -3,7 +3,6 @@ layout: pattern
|
|||||||
title: Naked Objects
|
title: Naked Objects
|
||||||
folder: naked-objects
|
folder: naked-objects
|
||||||
permalink: /patterns/naked-objects/
|
permalink: /patterns/naked-objects/
|
||||||
pumlid: LSX15i8W30N0g-W187jlaq9igH1uoO_r-BfrDs_kJKkFAc7zTW3B7qJ6LzuRZjZ2nSfKY2ANEQZrk1XiTFARKnLlkwR5W9Ww3VOVIFabDStjb08dGVcVz6mVX4aE6td5w5y0
|
|
||||||
categories: Architectural
|
categories: Architectural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
|
@ -3,7 +3,7 @@ layout: pattern
|
|||||||
title: Object Mother
|
title: Object Mother
|
||||||
folder: object-mother
|
folder: object-mother
|
||||||
permalink: /patterns/object-mother/
|
permalink: /patterns/object-mother/
|
||||||
pumlid:
|
pumlid: LOr13iCW30JlVKNx0E3UKxxYW9KGWK7sklb-wR6dtLbfj9k15DxRurKbDo_isfudCEsTaj8TZuhJTpVMF0GiY7dqL9lVjDHqqOT2OQk7X4a0grZgPAkaiL-S4Vh0kOYH_vVeskFyVMyiPUKN
|
||||||
categories: Creational
|
categories: Creational
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
@ -28,4 +28,4 @@ Use the Object Mother pattern when
|
|||||||
|
|
||||||
* [c2wiki - Object Mother](http://c2.com/cgi/wiki?ObjectMother)
|
* [c2wiki - Object Mother](http://c2.com/cgi/wiki?ObjectMother)
|
||||||
|
|
||||||
* [Nat Pryce - Test Data Builders: an alternative to the Object Mother pattern](http://www.natpryce.com/articles/000714.html)
|
* [Nat Pryce - Test Data Builders: an alternative to the Object Mother pattern](http://www.natpryce.com/articles/000714.html)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@startuml
|
@startuml
|
||||||
|
left to right direction
|
||||||
package com.iluwatar.observer {
|
package com.iluwatar.observer {
|
||||||
class App {
|
class App {
|
||||||
- LOGGER : Logger {static}
|
- LOGGER : Logger {static}
|
||||||
@ -71,10 +72,10 @@ package com.iluwatar.observer.generic {
|
|||||||
Weather --> "-currentWeather" WeatherType
|
Weather --> "-currentWeather" WeatherType
|
||||||
GWeather --> "-currentWeather" WeatherType
|
GWeather --> "-currentWeather" WeatherType
|
||||||
Weather --> "-observers" WeatherObserver
|
Weather --> "-observers" WeatherObserver
|
||||||
Hobbits ..|> WeatherObserver
|
Hobbits ..|> WeatherObserver
|
||||||
Orcs ..|> WeatherObserver
|
Orcs ..|> WeatherObserver
|
||||||
GHobbits ..|> Race
|
GHobbits ..|> Race
|
||||||
GOrcs ..|> Race
|
GOrcs ..|> Race
|
||||||
GWeather --|> Observable
|
GWeather --|> Observable
|
||||||
Race --|> Observer
|
Race --|> Observer
|
||||||
@enduml
|
@enduml
|
||||||
|
@ -3,7 +3,6 @@ layout: pattern
|
|||||||
title: Page Object
|
title: Page Object
|
||||||
folder: page-object
|
folder: page-object
|
||||||
permalink: /patterns/page-object/
|
permalink: /patterns/page-object/
|
||||||
pumlid: JSV14OGW30NGLjO28FVj9iOCua1Wme-sxnxtzjvMJLeS6ju-9p3NbyZvoQNYZ3sMkWo36hACJhN5ms2dYszEXwvQB4q6r6rHv_K3JIwQndwfW1Jo_npUyupUNW00
|
|
||||||
categories: Testing
|
categories: Testing
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
@ -12,7 +11,7 @@ tags:
|
|||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
|
|
||||||
Page Object encapsulates the UI, hiding the underlying UI widgetry of an application (commonly a web application) and providing an application-specific API to allow the manipulation of UI components required for tests. In doing so, it allows the test class itself to focus on the test logic instead.
|
Page Object encapsulates the UI, hiding the underlying UI widgetry of an application (commonly a web application) and providing an application-specific API to allow the manipulation of UI components required for tests. In doing so, it allows the test class itself to focus on the test logic instead.
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
@ -22,11 +21,10 @@ Page Object encapsulates the UI, hiding the underlying UI widgetry of an applica
|
|||||||
|
|
||||||
Use the Page Object pattern when
|
Use the Page Object pattern when
|
||||||
|
|
||||||
* You are writing automated tests for your web application and you want to separate the UI manipulation required for the tests from the actual test logic.
|
* You are writing automated tests for your web application and you want to separate the UI manipulation required for the tests from the actual test logic.
|
||||||
* Make your tests less brittle, and more readable and robust
|
* Make your tests less brittle, and more readable and robust
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Martin Fowler - PageObject](http://martinfowler.com/bliki/PageObject.html)
|
* [Martin Fowler - PageObject](http://martinfowler.com/bliki/PageObject.html)
|
||||||
* [Selenium - Page Objects](https://github.com/SeleniumHQ/selenium/wiki/PageObjects)
|
* [Selenium - Page Objects](https://github.com/SeleniumHQ/selenium/wiki/PageObjects)
|
||||||
|
|
||||||
|
1
pom.xml
1
pom.xml
@ -136,6 +136,7 @@
|
|||||||
<module>object-mother</module>
|
<module>object-mother</module>
|
||||||
<module>converter</module>
|
<module>converter</module>
|
||||||
<module>guarded-suspension</module>
|
<module>guarded-suspension</module>
|
||||||
|
<module>balking</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
@ -3,6 +3,7 @@ layout: pattern
|
|||||||
title: Promise
|
title: Promise
|
||||||
folder: promise
|
folder: promise
|
||||||
permalink: /patterns/promise/
|
permalink: /patterns/promise/
|
||||||
|
pumlid: DOqv4i8m301xNW4FYDLJvIl2rYHYBDcZWtmVKr3jDZkxUw15IhyzM6lFHcdzVaPCVm8ONkNWEFELJbQ71ccKEWIuvuKhXJT-S6laVEWsCO9C7GHz2KmRmav0KVzUqgJCtsydROjV
|
||||||
categories: Concurrency
|
categories: Concurrency
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@startuml
|
@startuml
|
||||||
|
left to right direction
|
||||||
package com.iluwatar.promise {
|
package com.iluwatar.promise {
|
||||||
class App {
|
class App {
|
||||||
- DEFAULT_URL : String {static}
|
- DEFAULT_URL : String {static}
|
||||||
@ -70,9 +71,9 @@ package com.iluwatar.promise {
|
|||||||
+ lowestFrequencyChar(charFrequency : Map<Character, Integer>) : Character {static}
|
+ lowestFrequencyChar(charFrequency : Map<Character, Integer>) : Character {static}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TransformAction --> "-src" Promise
|
|
||||||
TransformAction --+ Promise
|
TransformAction --+ Promise
|
||||||
|
TransformAction --> "-src" Promise
|
||||||
ConsumeAction --+ Promise
|
ConsumeAction --+ Promise
|
||||||
ConsumeAction --> "-src" Promise
|
ConsumeAction --> "-src" Promise
|
||||||
Promise --|> PromiseSupport
|
Promise --|> PromiseSupport
|
||||||
@enduml
|
@enduml
|
||||||
|
@ -3,9 +3,8 @@ layout: pattern
|
|||||||
title: Publish Subscribe
|
title: Publish Subscribe
|
||||||
folder: publish-subscribe
|
folder: publish-subscribe
|
||||||
permalink: /patterns/publish-subscribe/
|
permalink: /patterns/publish-subscribe/
|
||||||
pumlid: PSZB3SCm203GLTe1RExT1XCKKs5YyMdMR--zFRsd66aTNAwFcRdZ1U1uzrDorgXWfykIBJjT2qJhnaI7Dtwm7HnoMjkOoMu12-C7s3LKOhQe4UGo63ZfVtlvwhkMVW40
|
|
||||||
categories: Integration
|
categories: Integration
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
- EIP
|
- EIP
|
||||||
- Apache Camel™
|
- Apache Camel™
|
||||||
|
@ -3,7 +3,7 @@ layout: pattern
|
|||||||
title: Queue based load leveling
|
title: Queue based load leveling
|
||||||
folder: queue-load-leveling
|
folder: queue-load-leveling
|
||||||
permalink: /patterns/queue-load-leveling/
|
permalink: /patterns/queue-load-leveling/
|
||||||
pumlid:
|
pumlid: ROux3W8n30LxJW47IDnJxLLCOcM376VnP_VwX9xgZKOQwMtcg1w3RuykXQDIADztzyEU08fNRjttU8MHbYbEuhdC0PtZmfN26qzCbQmtIGUwauh1G5i0dw2Wn1DhOZg9kpGWB_zy3Xtv-FtOIEhQBm00
|
||||||
categories: Other
|
categories: Other
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
@ -34,4 +34,4 @@ for both the task and the service.
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Microsoft Cloud Design Patterns: Queue-Based Load Leveling Pattern](https://msdn.microsoft.com/en-us/library/dn589783.aspx)
|
* [Microsoft Cloud Design Patterns: Queue-Based Load Leveling Pattern](https://msdn.microsoft.com/en-us/library/dn589783.aspx)
|
||||||
|
@ -4,8 +4,9 @@ title: Reactor
|
|||||||
folder: reactor
|
folder: reactor
|
||||||
permalink: /patterns/reactor/
|
permalink: /patterns/reactor/
|
||||||
pumlid: DSR14OGm20NGLjO23FVj1f7Hx2Ga0nzjVxtuJc-f9YrtJM-V4vZn9NA-or5nvfQXBiEWXYAZKsrvCzZfnnUlkqOzR9qCg5jGvtX2hYmOJWfvNz9xcTdR7m00
|
pumlid: DSR14OGm20NGLjO23FVj1f7Hx2Ga0nzjVxtuJc-f9YrtJM-V4vZn9NA-or5nvfQXBiEWXYAZKsrvCzZfnnUlkqOzR9qCg5jGvtX2hYmOJWfvNz9xcTdR7m00
|
||||||
|
pumlformat: svg
|
||||||
categories: Concurrency
|
categories: Concurrency
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
- Difficulty-Expert
|
- Difficulty-Expert
|
||||||
- I/O
|
- I/O
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@startuml
|
@startuml
|
||||||
|
left to right direction
|
||||||
package com.iluwatar.reactor.framework {
|
package com.iluwatar.reactor.framework {
|
||||||
abstract class AbstractNioChannel {
|
abstract class AbstractNioChannel {
|
||||||
- channel : SelectableChannel
|
- channel : SelectableChannel
|
||||||
@ -147,9 +148,9 @@ App --> "-channels" AbstractNioChannel
|
|||||||
DatagramPacket ..+ NioDatagramChannel
|
DatagramPacket ..+ NioDatagramChannel
|
||||||
App --> "-dispatcher" Dispatcher
|
App --> "-dispatcher" Dispatcher
|
||||||
ChangeKeyOpsCommand --+ NioReactor
|
ChangeKeyOpsCommand --+ NioReactor
|
||||||
LoggingHandler ..|> ChannelHandler
|
LoggingHandler ..|> ChannelHandler
|
||||||
NioDatagramChannel --|> AbstractNioChannel
|
NioDatagramChannel --|> AbstractNioChannel
|
||||||
NioServerSocketChannel --|> AbstractNioChannel
|
NioServerSocketChannel --|> AbstractNioChannel
|
||||||
SameThreadDispatcher ..|> Dispatcher
|
SameThreadDispatcher ..|> Dispatcher
|
||||||
ThreadPoolDispatcher ..|> Dispatcher
|
ThreadPoolDispatcher ..|> Dispatcher
|
||||||
@enduml
|
@enduml
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@startuml
|
@startuml
|
||||||
|
left to right direction
|
||||||
package com.iluwatar.servicelayer.hibernate {
|
package com.iluwatar.servicelayer.hibernate {
|
||||||
class HibernateUtil {
|
class HibernateUtil {
|
||||||
- LOGGER : Logger {static}
|
- LOGGER : Logger {static}
|
||||||
@ -143,18 +144,18 @@ MagicServiceImpl --> "-spellbookDao" SpellbookDao
|
|||||||
MagicServiceImpl --> "-spellDao" SpellDao
|
MagicServiceImpl --> "-spellDao" SpellDao
|
||||||
Spellbook --> "-spells" Spell
|
Spellbook --> "-spells" Spell
|
||||||
Spellbook --> "-wizards" Wizard
|
Spellbook --> "-wizards" Wizard
|
||||||
DaoBaseImpl ..|> Dao
|
DaoBaseImpl ..|> Dao
|
||||||
MagicServiceImpl ..|> MagicService
|
MagicServiceImpl ..|> MagicService
|
||||||
Spell --|> BaseEntity
|
Spell --|> BaseEntity
|
||||||
SpellDao --|> Dao
|
SpellDao --|> Dao
|
||||||
SpellDaoImpl ..|> SpellDao
|
SpellDaoImpl ..|> SpellDao
|
||||||
SpellDaoImpl --|> DaoBaseImpl
|
SpellDaoImpl --|> DaoBaseImpl
|
||||||
Spellbook --|> BaseEntity
|
Spellbook --|> BaseEntity
|
||||||
SpellbookDao --|> Dao
|
SpellbookDao --|> Dao
|
||||||
SpellbookDaoImpl ..|> SpellbookDao
|
SpellbookDaoImpl ..|> SpellbookDao
|
||||||
SpellbookDaoImpl --|> DaoBaseImpl
|
SpellbookDaoImpl --|> DaoBaseImpl
|
||||||
Wizard --|> BaseEntity
|
Wizard --|> BaseEntity
|
||||||
WizardDao --|> Dao
|
WizardDao --|> Dao
|
||||||
WizardDaoImpl ..|> WizardDao
|
WizardDaoImpl ..|> WizardDao
|
||||||
WizardDaoImpl --|> DaoBaseImpl
|
WizardDaoImpl --|> DaoBaseImpl
|
||||||
@enduml
|
@enduml
|
||||||
|
Reference in New Issue
Block a user