On task level, architecture means defining which modules are taking care of what responsibility, and how they play together.
We recommend the top-level architecture to satisfy the following restrictions: === Top-Level architecture ===
* Network-distances between the database server and the application server (e.g., web services) should be minimal for performance reasons.
* One should always plan for a staging strategy with multiple environments for QA.
We recommend the task=== Task-level architecture to satisfy the following restrictions:===
* Custom code should always be developed in a plugin where possible, with the {{UBIK}} custom code just connecting the plugin code with the {{UBIK}} objects.
* Custom code should be arranged so heavy-duty processes (involving much data and complex calculations) are performed on powerful machines (and not on the mobile client).
A good way to design a data model is to create an [https://de.wikipedia.org/wiki/Entity-Relationship-Modell Entity-Relationship Diagram]. It is recommended to do so in the scope of a Technical Design (see [https://wiki.augmensys.com/index.php?title=HowTo:Organize_UBIK_Development#tab=Requirement_Supply_Chain Requirement Supply Chain]).
=== Object-oriented and relational ===
{{UBIK}} is an object-oriented framework, so the data model should reflect entities of the customer's business processes (e.g., invoices and products), as so-called MetaClasses.
One can use relations and references to create n:m and 1:n connections and dependencies between such entities (e.g., the relationships between invoices, invoice items and products).
An important aspect in data modelling, especially for the representation in relational databases, is [https://en.wikipedia.org/wiki/Database_normalization normalization].
=== Basic data model ===
For a use-case to be satisfied with {{UBIK}}, we should create a basic data model for the entities involved in the relevant customer's business processes, without respect to presentation in {{UBIK}} first.
This is because we need to rely on a correct and well-defined concept of the data on a fundamental level.
* As a consequence, there is redundancy in the data and the data model is inconsistent with reality, leading to conceptual problems when using the data later.
=== Extended data model ===
The basic data model might not be very good for representation on the mobile application, because it would lead to mixing multiple different entities in the same view.
This is a problem because it makes the UI customizing complex and prone to performance issues.
There are also some quick hints we can drop for you to avoid many problems.
=== Custom code for MetaClasses:===
* Don't use the "OnSaved" event if you want to modify any object as a result of another object being saved. Use "OnPrepareForSave" instead, to avoid complex saving recursions.
* Use a custom plugin to create a nice architecture for your code, using the life cycle events only to call it.
=== Parallelism:===
* Avoid multi-threading, but if you have to implement parallel tasks, use locking wisely to avoid dead-locks.
* Keep in mind that multiple users could work on the same objects, i.e., your customizing can be executed in parallel, on different processes. This means you have to make sure your code doesn't interfere with itself. Mostly this is relevant for updating and reading from the database, where one process can update a value while another one is assuming a different value.
=== Performance:===
* Apply caching to reuse previously processed data and to avoid doing the same thing more than once, but clean up your cache if it becomes invalid.
Avoiding crashes:
* Check every variable for being null before you use it.
=== Well-formed code:===
* Apply the principles of object-oriented programming (OOP) and the C# coding conventions.
* For every responsibility in the code, there should be a dedicated software module. An optimal distribution of responsibility will often make your code perform better and easier to understand and maintain.
= Mobile =
For mobile features, it is important to consider some basic principles the client works by:. === Object hierarchy and navigation ===
* The navigation structure is based on the hierarchic relations between UBIK objects.
* One UBIK object is the primary context of every page, and a list of its children can be accessed from there.
* Showing multiple hierarchy levels of objects on the same page is most likely a performance killer and hard to maintain, too.
=== XAML customizing ===
* Every area of the application has a separate XAML file one can customize to adjust the layout.
* There is a central Themes XAML file for adjustments that can be reused in multiple areas.
* You can use the [[Developer_Mode]] to find out which XAML file to adapt for a certain area in the UI.
=== Connectivity ===
* When designing a use-case, it is important to consider whether a feature must be available in offline mode, in online mode, or both; for offline use, the respective content must be made available on the device when there's the possibility (since it can't be fetched from the server on demand later).
=== Custom or Out-of-the-box? ===
* The usage of out-of-the-box features is highly recommended and preferred over the development of new custom features.
* New, custom features are problematic because of their need to be quality-assured, which is a lot of effort that was probably already invested for standard features.