This desktop application is developed based on the GUI frameworks JavaFX. A user creates (bike-, hike-, running-, etc) tours in advance and manages the logs and statistical data of accomplished tours. The tours, logs and directions are stored in a postreSQL database. The tour information is collected from the MapQuest API and the map images are stored locally on a file-system.
This application is divided into 3 layers (view, business and data access layers). The application configuration (application.properties file in the config package) determines which classes from the BL and DAL will be instantiated. More details below.
This layer manages the GUI and the user interaction
Views: 3 dialogs (add/edit Tour, add/edit TourLog, exportReport) and a toursView for displaying Tour and Log List.
This layer imports class from the DAL which are instantiated depending on which concrete DALFactory implementation is chosen. An IAppManager interface allows choosing between the AppManagerMock (which returns hardcoded), and the AppManagerDB class (which connects to the DAL). An AppManagerFactory return a singleton of the chosen IAppManager concrete implementation.
This layer calls the DAL to manage Tours, Logs and TourDirection, creation of reports, calculate TourStats and manage TourDirection's
Libraries:
1) log4j: logging application library for recoding app activity. Used levels: INFO, DEBUG, WARN, ERROR.
2) lombok: the mainly used annotations @Data, @Builder, @AllArgsConstructor
allow faster coding process.
I realized I should avoid using new
to instantiate new Objects. Instead, using Object.builder.build()
allows a more flexible architecture. In case you modify the properties of a class having already created
mocked objects for test with new
, every new statement needs to be updated. With Builder this is avoided.
3) itextpdf - html2pdf: to create report using html. Which simplifies the styling process.
4) junit: for unit testing. used also the @Order
annotation to force the test to follow the same
execution order.
5) mockito: allows mocking objects for each unit test.
6) gson: offers JSON data-binding support. Used to deserialize JSON MapQuest API response body into
a Response
object
7) checkstyle: to check coding style and to ensure standards and good practices. currently disabled
8) surefire-report: creates html reports of unit tests. Displayed are details like: Packages and Classes, coverage, test methods names, Failure tests or skipped tests with reason, Execution time taken by each method. Open Report
9) javadoc: for documentation. It automatically generates html documentation for Classes, properties and methods
10) maven-site-plugin: Application html summary report. Open Report
11) jacoco: to check test unit code coverage Open Report
AppManagerFactory
.
The factory returns a singleton of a concrete AppManager abstraction.
This prevents that more than one instance/object of the same class is created.IController
interface class variable.
This allows to call methods from any Controller class, which implement the IController
interface (Double Dispatch)IDALFactory
with DALOracleFactory and DALPostgresFactory depending on which SQL DB is to be implemented.I started creating unit test from the DAL to ensure before testing higher layers that the basic functionality was achieved and focusing afterwards in only the logic of the method not the others related to it. Some tests can not be considered as unit test because they test for example that the API is working properly. JUnit allows to determine the order of execution of the test which allows for example to create a Tour, then search a term from this specific Tour and to delete it at the end. Usually test are executed in a "random" order. This option made the test development easier and more efficient.
Total test: 34
Displays the steps/direction of each tour in the Step Tab of the GUI. The maneuvers are to be found in the steps objects of the API response and stored into TourDirection objects. The creation of the viewList slows down when needing to access in each loop to the online images. That's the reason why the most frequent ones were stored locally. The ones which are not stored locally are loaded from online url.
100 hrs