@startuml package com.iluwatar.async.method.invocation { class App { - LOGGER : Logger {static} + App() - callback(name : String) : AsyncCallback<T> {static} - lazyval(value : T, delayMillis : long) : Callable<T> {static} - log(msg : String) {static} + main(args : String[]) {static} } interface AsyncCallback<T> { + onComplete(T, Optional<Exception>) {abstract} } interface AsyncExecutor { + endProcess(AsyncResult<T>) : T {abstract} + startProcess(Callable<T>) : AsyncResult<T> {abstract} + startProcess(Callable<T>, AsyncCallback<T>) : AsyncResult<T> {abstract} } interface AsyncResult<T> { + await() {abstract} + getValue() : T {abstract} + isCompleted() : boolean {abstract} } class ThreadAsyncExecutor { - idx : AtomicInteger + ThreadAsyncExecutor() + endProcess(asyncResult : AsyncResult<T>) : T + startProcess(task : Callable<T>) : AsyncResult<T> + startProcess(task : Callable<T>, callback : AsyncCallback<T>) : AsyncResult<T> } -class CompletableResult<T> { ~ COMPLETED : int {static} ~ FAILED : int {static} ~ RUNNING : int {static} ~ callback : Optional<AsyncCallback<T>> ~ exception : Exception ~ lock : Object ~ state : int ~ value : T ~ CompletableResult<T>(callback : AsyncCallback<T>) + await() + getValue() : T + isCompleted() : boolean ~ setException(exception : Exception) ~ setValue(value : T) } } CompletableResult ..+ ThreadAsyncExecutor ThreadAsyncExecutor ..|> AsyncExecutor CompletableResult ..|> AsyncResult @enduml