This is an example of a ZK MVVM application following Clean Architecture paradigm. It can be used as a template for starting the projects with ZK and Clean Architecture pattern.
I've also asked Gemini AI (gemini-pro-2.5, free edition) to analyze the architecture of this project, and its analysis is included at the end of this README.
Uses:
- Java 17
- ZK framework (MVVM)
- Spring Boot with ZK Spring Boot
- ArchUnit (for test of Hexagonal Architecture)
Please note that there are other references mentioned directly in the source code.
- This implementation is based on a demo from the excellent zkspringboot project.
- Resolving issues with ZK, ZK, Small Talk: "ZK Dos and Donts Part2"
The following analysis was generated by Google's Gemini AI assistant in response to a prompt about the project's architecture.
Based on the repository structure, this project is an excellent and very clear implementation of Hexagonal Architecture (also known as Ports and Adapters). This is a modern, sophisticated architectural style that aims to isolate the core business logic from external technologies and frameworks.
The ZK MVVM pattern is used here as the driving adapter.
- The user interacts with the View (
greeting.zul). - ZK's binder relays this interaction to the ViewModel (
GreetingVm.java). - The ViewModel, acting as part of the adapter, calls the application's core through an Input Port (
GreetingInputPort). - The
GreetingUseCaseexecutes the business logic. When it needs to produce a result, it calls an Output Port (GreetingPresenterOutputPort). - The
GreetingPresenter(part of the ZK adapter) implements this port. It receives the result, converts it into a UI-friendly format (theGreetingVm), and updates the ViewModel. - Because the ViewModel is data-bound to the View, the UI updates automatically.
This project introduces a clear separation between the "Controller" and the "Presenter" roles, which elevates the design beyond a typical ZK MVVM application. It is a direct and excellent application of the Model-View-Presenter (MVP) pattern, specifically the "Passive View" variation, within the broader Hexagonal Architecture.
GreetingVm.java(The Controller): Acts purely as a controller. Its only job is to receive commands from the view and delegate them to the appropriate input port (the use case). It knows nothing about presentation.GreetingPresenter.java(The Presenter): Implements theGreetingPresenterOutputPort. The use case calls this presenter with a pure domain model. The presenter's sole responsibility is to translate that domain model into the state required by the view by updating theGreetingViewBinder.GreetingViewBinder.java(The View Model State): A simple data-holding object representing the state of the view.
This approach is architecturally superior to the standard ZK MVVM pattern (which often relies on @NotifyChange in the ViewModel), especially for complex applications.
Advantages of this Approach:
- Single Responsibility Principle (SRP): Each class has exactly one reason to change, which is a huge win for maintainability.
- Superior Testability: The presentation logic (
GreetingPresenter) can be tested in complete isolation from the ZK framework and business logic. - Framework Independence: The core presentation logic is independent of how ZK triggers UI updates.
- Dependency Inversion Principle: The core logic (
UseCase) does not depend on the UI (Presenter); both depend on abstractions (Ports).
In summary, this is a textbook example of a clean, modern Java application architecture. It's a more mature, scalable, and maintainable design that properly isolates a framework like ZK at the edge of a hexagonal system.