The following text can be seen as a
concept documentation. It explains foundational decisions, as well
as design and architecture patterns used by the framework. It helps
in understanding the ideas behind the framework and how it is
supposed to work.
1.1) Domain Driven Design
One of the largest problems in software projects is not technology,
but language and semantics. One might think it is easy to build
great products with great tools, but this will ultimately fail when
requirements are misunderstood or the code is unmaintainable over
the long term. Just because it does not reflect the problem domain
well enough for which it is purposed. Domain
Driven Design (DDD) tackles this problem by providing best
practices for understanding the domain and utilizing that knowledge
throughout the whole development process. It gives guidelines about
how to make communication easier by defining an ubiquitious
language. This ubiquitous language is used by all team members,
including domain experts and engineers, to prevent miscommunication
that originates from different vocabulary being used. Engineers
represent the domain knowledge in a domain
model. This can be done by creating documentation with the Unified
Modeling Language (UML) using class diagrams, activity diagrams
and such, then translating it to code following the DDD principles
either manually or using Model
Driven Architecture (MDA) and Model
Driven Software Development (MDSD). Alternatively you can simply
do this in your mind without any modeling or code generation tools,
skipping the intermediate step and translating the model directly
into code. In any case the idea here is to use the ubiquitous
language and domain model consistently for communication,
documentation and code.
One of the problems of the DDD
introductory literature is that it focuses a lot on the business
layer (which they call domain layer) and thus more on the backend
side of application development. No criticism here, since their
patterns there are great and the idea of using a distinction
between value objects, entities, repositories and services (among a
few more) helps structuring that side of applications a lot. But
DDD can be applied to the presentation layer as well with great
benefits. When researching in that direction, one easily stumbles
upon the next pattern this framework is based on, the ...
1.2) Naked Objects Pattern
The Naked
Objects Pattern is building on the premise, that a good domain
model is suitable to be externalized as a user interface. And vice
versa that the requirement of externalizing it, results in a better
domain model. How this externalization of a domain model looks like
in practice is demonstrated by the following example:
Domain Model Gets Converted to
User Interface
Here you see that:
- each class is represented individually as an area in the
UI
- getters and setters result in input fields
- a list of contracts associated with the customer results
in a table being displayed
- action methods result in buttons
- each element in the UI can be identified via a bean path
in the model (e.g. 'name', 'contract.status' or 'address.street'
relative to the customer class)
For this to work, you will notice that the domain model not only
contains the state (properties), but also the logic about how to
manipulate it (actions). The model thus becomes intelligent and the
Naked Objects Pattern uses that intelligence to make it available
as an user interface (UI). To understand this better, please see
the next graphic for a comparison of applications based on the Model
View Controller (MVC) Pattern and applications based on the Naked
Objects Pattern:
MVC vs Naked Objects in a
Layered Architecture
Adaption of an image made by Daniel S. Haischt which was originally publicized
on Wikipedia,
licensed under CC
BY-SA 3.0
With this it becomes apparent what
the Naked Objects Pattern is aiming for. By being able to match the
views to the models, you can completely remove the controller layer
and automate it using binding conventions to the intelligent
models. The application thus becomes simpler to understand and
easier to maintain, since you are forced not to allow the clutter
between the view and model to appear in the first place. In MVC,
the controller layer is normally implemented to handle differences
in the layers, but the Naked Objects Pattern makes this obsolete.
1.3) RAD & CRUD vs Naked Objects
The Naked Objects Pattern goes even further conceptually and says
it can completely generate the view for you based on those binding
conventions. In practice this idea is often manifested in Rapid
Application Development (RAD) and Create
Read Update Delete (CRUD) frameworks. When they also promise to
provide data driven user interfaces, you will mostly see fancy
looking web pages with lots of tables that display database
entities with common data manipulation facilities you are used from
CRUD. Those frameworks sure are nice for CRUD applications, but
fail miserably for more complex and customized user interfaces. As
soon as you try to deviate from their chosen conventions and try to
extend their views or even modify them, these frameworks will in
the worst case make it so hard for you, that you are forced to
writing your view from scratch in those special cases. RAD and
rapid prototyping is nice and this framework is also usable in this
direction, but a good framework should give you the freedom to
extend and modify the generated views as easily as possible. The
idea to provide this freedom in this framework is by embracing
Wicket instead of hiding its existence, thus still making easily
accessible everything you can do with Wicket. Since Wicket is a MVC
framework, applying the Naked Objects Pattern on it is easy and has
to just focus on automating parts of the Controller and View for
you while still allowing you to use your own code as a replacement
for the defaults where needed.
1.4) Document View Architecture
One more problem with many CRUD
frameworks is that they usually bind to entities from the
persistence layer and are thus interwoven with the data management.
When you want to use entities for the UI you might have to extend
them with UI specific annotations and methods for e.g.:
- ordering of fields
- internationalizing strings
- providing choices for combo boxes
- retrieving data from tables or saving data to tables
- converting the data into a different form to be displayed
- opening modal dialogs or displaying status messages
This for example has the following
drawbacks:
- you cannot reuse your existing (maybe legacy) entities for
new views, since they might not match in structure
- you might need to call repositories or services from your
entity while your architecture suggests keeping them stupid, for
data holding purposes only
- you might accidentally mix the DDD concepts of service,
repository and entity and put everything in your entities
- you cannot reuse the entities easily in other modules
since they are bound to your UI framework
- refactorings in your UI might lead to refactorings in your
database and vice versa
- it is not easy to write reusable Wicket pages, panels and
components when they are bound to a specific persistence layer
framework
- some entity hierarchies might be so complex that they have
to be split among multiple views/tabs/wizards, each having
different requirements on the model and needs to hide things
- you may want different perspectives on the same data but
the entity class does not match all perspectives properly
Here the Document
View Architecture comes in handy. Instead of putting everything
into your entities and using them as your models for the UI, you
implement documents that match directly to the desired views you
want. The documents handle data retrieval and manipulation using
services and repositories and provide adjusted data from the
entities where needed or just delegate to those directly where
appropriate. The documents can even reuse entity classes completely
where possible and extend them from the outside by providing
additions and overrides for the nested properties and actions.
Applying the Document View Architecture enables this framework to
give you the freedom of choosing your own frameworks for the
business and persistence layer. This makes it a lightweight web
framework instead of a complete development platform.