You’re given the task of writing a simple console version of a drawing program. At this time, the functionality of the program is quite limited but this might change in the future. In a nutshell, the program should work as follows:
-
Create a new canvas
-
Start drawing on the canvas by issuing various commands
-
Quit
Command Description
C w h Should create a new canvas of width w and height h.
L x1 y1 x2 y2 Should create a new line from (x1,y1) to (x2,y2). Currently only
horizontal or vertical lines are supported. Horizontal and vertical lines
will be drawn using the 'x' character.
R x1 y1 x2 y2 Should create a new rectangle, whose upper left corner is (x1,y1) and
lower right corner is (x2,y2). Horizontal and vertical lines will be drawn
using the 'x' character.
B x y c Should fill the entire area connected to (x,y) with "colour" c. The
behavior of this is the same as that of the "bucket fill" tool in paint
programs.
Q Should quit the program.
Below is a sample run of the program. User input is prefixed with enter command:
enter command: C 20 4
----------------------
| |
| |
| |
| |
----------------------
enter command: L 1 2 6 2
----------------------
| |
|xxxxxx |
| |
| |
----------------------
enter command: L 6 3 6 4
----------------------
| |
|xxxxxx |
| x |
| x |
----------------------
enter command: R 14 1 18 3
----------------------
| xxxxx |
|xxxxxx x x |
| x xxxxx |
| x |
----------------------
enter command: B 10 3 o
----------------------
|oooooooooooooxxxxxoo|
|xxxxxxooooooox xoo|
| xoooooooxxxxxoo|
| xoooooooooooooo|
----------------------
enter command: Q
I make the assumption that the size of the canvas is not more than the length of a single text screen 80 characters , what acceptable to most console users.
Since at this stage the requirements are not detailed, it is assumed that the program behaves like a raster paintbrush, those figures can intersect and the paint fills the border if it gets into
-
Please install LATEST! version java 12
-
Please install latest version gradle 5.1.1
-
Simpliest way - is to use project’s gradle wrapper (with smallest gradle-wrapper.jar inside for gradle downloading). But some organizations (banks:) do not allow projects to submit binary files. The alternative approach to install gradle and generate gradle wrapper
gradle wrapper
-
for building project use gradle plugin
gradlew build
-
for running use gradle command for generate distribution
gradlew bootDistZip
-
goto folder and unpack
/riso/build/distributions/riso-boot-1.0.0.zip
-
run java programm
riso-boot-1.0.0/bin/riso.bat
-
Note
|
sometimes when running on windows OS you may see a blank screen - then you need to press any key |
Note
|
if you run directly under gradle,due to spring shell issue, you will not find first prompt message |
-
for convenience (not to look for them in the build folder) documents (related to the program) are copied to the docs folder
-
if you want, for installing the same environment in IntellijIDEA set File—Settings repository = [email protected]:wilmerkrisp/idesettingrepository.git
and app template used https://github.com/wilmerkrisp/apptemplate/tree/master/winter
Imagine that this application is intended for employees of Bank branches and helps them to mark the workspace for scanning documents
Thus the app is relates to the "Business support" domain for banking standard BIAN
-
Since this application is an internal banking software, the assumption is used - the lack of internationalization
-
cover the test code of the most important classes of the subject area in addition to unit tests, integration and functional tests have also been created
gradlew test //for unit testing gradlew testFunctional //for functional testing gradlew testIntegration //for integration testing
-
gradle used (see /build.gradle), please use gradle wrapper ./gradlew for running tasks
-
project name inside settings.gradle (rootProject.name)
-
main class name and version setted inside build.gradle
-
Note
|
IDE—Settings—Build—Gradle: select: Gradle wrapper customization in build script delegate IDE build/run actions to gradle |
-
project source sets:
-
jmh - for benchmarking
-
main
-
test
-
testFunctional
-
testIntegration
-
-
well-known libraries are widely used (Guava, Apache commons)
-
in accordance with the principles of reference architectures of TOGAF architecture, the most well-established components are transferred to the library, here I use my own library
-
Lombok annotations are widely used, see configuration inside build.gradle (then /lombok.config autogenerated)
-
logback used for logging,
-
Note
|
configuration file at /src/main/resources/logback-spring.xml see log file at /riso.log |
-
The app is SPA java console application, in order not to reinvent the wheel, the Spring Shell framework for console applications is taken as a basis (as there are no performance/size requirements for the application).
-
this application uses patterns from the classifier/vocabulary
-
partially used functional approach (Vavr, Cyclops)
-
wrapping checked exceptions into bool, Try, Either, flow events, Optional depending on situations
-
pattern matching inside Switch
-
so as the excitement of the exceptions is expensive then all errors are reported as events of the flow
-
-
reactive approach is used (Spring Reactor) for further parallel scaling of threads
-
in the future, you should call all commands from the same Flux (Flux.create for example as in the Android reactive applications), place processing (domain methods) in a separate thread and draw the result back in the UI thread
-
-
the following coding standards and conventions were used
-
made benchmark test: the most interesting test of this application: fill lines O(n^2) complexity (as can be seen from the graph below)
where n - is the size of the filled areagradle jmh
-
profiling an application, please note that an external jprofile installation is required.
gradle saveProfile
-
The application is designed for one user.
-
In performance it is assumed that it will create 100 canvases a day.
-
There are no requirements for the size of the application (the virtual workplace of a Bank employee takes no more than 2 gigabytes).
-
Requirements to the level of application criticality by Bank classification: BO (business operational)
-
monitoring and recovery from failures outside the scope of this work
-
servers hardware, equipmetnt outside the scope of this work