Changes
Created page with "Customizing {{UBIK}} is a complex endeavor. In this article, we aim to provide a guide and best practices making this task as straight-forward as possible. <!-- DO NOT REMOVE..."
Customizing {{UBIK}} is a complex endeavor. In this article, we aim to provide a guide and best practices making this task as straight-forward as possible.
<!-- DO NOT REMOVE THIS -->{{Template:HowTo/Begin}}<!-- DO NOT REMOVE THIS -->
= Strategy =
It's important that development of your project is structured well in order to maximize the positive impact of every step you take. An unstructured project will lead to the frequent dismissal of invalid results, going back and forth unnecessarily, because things are done in the wrong order, ignoring the dependencies between tasks.
As a prerequisite for the rest of this article, please consider the following guide:
[[HowTo:Organize_UBIK_Development]]
= Architecture =
The architecture is something to consider on a rather abstract level, in the beginning of a project, but also on the level of a single task.
In the context of a whole project, architecture means defining whether there are multiple {{UBIK}} installations on different sites, what products will be involved and how they are connected topologically.
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:
* 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-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).
* Actually, all of the effort should be done on the server if possible, with the client just using out-of-the-box features. This won't be feasible in all cases, though.
* 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.
* Give all variables, methods and classes really good and human readable names. Good naming and well-structured source code is better than any kind of comments.
= Data Model =
== 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).
Properties with different data types can be modeled for every entity, and one such MetaClass can inherit the properties from another (e.g., there could be a MetaClass "SAFETY_INSTRUCTIONS" inheriting the "Filepath" property from a "DOCUMENT" MetaClass).
== 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.
== 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.
But, worry not. {{UBIK}} is designed to provide views and transformations of a basic data model.
So, we can create an extension of the original data model in a second design phase, where we provide a model tailored to the (mobile) use-case.
This extension can happen on multiple levels:
* A new layer of MetaClasses can be used to perform calculations on and combine more basic data.
* A View can provide a custom hierarchy between instances using relations, queries and custom implementations of view-connections between objects (so-called ViewItems).
* A Scope can define how to display objects on the mobile application, allowing for a custom representation in the UI.
Also, {{UBIK}} comes with a lot of features one can apply to influence the behavior of (data on) the mobile client, ranging from inter-dependent tasks and work-packages to dynamic selective lists.
= Algorithm =
Most {{UBIK}} customizings introduce custom code performing more or less complex data processing tasks.
The algorithm resulting from custom code can be highly distributed because of the way the life cycle of {{UBIK}} objects can be customized.
But it can also be a single interface with a third party system that has to crawl through a lot of data and perform many operations on them.
In any case, it pays off to get a good idea of the virtual processes resulting from the customizing for multiple reasons:
* Algorithms can scale very badly if their time complexity is not considered.
* Especially distributed algorithms can misbehave seriously and are very hard to maintain if they are not understood thoroughly.
These two reasons should be sufficient to invest a substantial amount of effort into making the algorithm:
* Easy to understand
* Scale well with respect to more input
There are also some quick hints we can drop for you to avoid many problems:
* 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.
* 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.
* Avoid multi-threading, but if you have to implement parallel tasks, use locking wisely to avoid dead-locks.
* Check every variable for being null before you use it.
= Client UI =
For the client UI, it is important to consider some basic principle the client works by:
* 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.
* 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.
* 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.
<!-- DO NOT REMOVE THIS -->{{Template:HowTo/End}}<!-- DO NOT REMOVE THIS -->
==See also==
* [[HowTo:Organize_UBIK_Development]]
* [[Design_object-oriented_data_models]]
* [[Entity_Data_Model]]
* [[XAML]]
* [[Xamarin_XAML]]
* [[XAML_Basics]]
* [[XAML_Best_practices]]
[[Category:How-To|Design a Customizing]]
[[Category:Best Practices (internal)|Design a Customizing]]
[[Category:Resources (internal)|Design a Customizing]]
<!-- DO NOT REMOVE THIS -->{{Template:HowTo/Begin}}<!-- DO NOT REMOVE THIS -->
= Strategy =
It's important that development of your project is structured well in order to maximize the positive impact of every step you take. An unstructured project will lead to the frequent dismissal of invalid results, going back and forth unnecessarily, because things are done in the wrong order, ignoring the dependencies between tasks.
As a prerequisite for the rest of this article, please consider the following guide:
[[HowTo:Organize_UBIK_Development]]
= Architecture =
The architecture is something to consider on a rather abstract level, in the beginning of a project, but also on the level of a single task.
In the context of a whole project, architecture means defining whether there are multiple {{UBIK}} installations on different sites, what products will be involved and how they are connected topologically.
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:
* 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-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).
* Actually, all of the effort should be done on the server if possible, with the client just using out-of-the-box features. This won't be feasible in all cases, though.
* 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.
* Give all variables, methods and classes really good and human readable names. Good naming and well-structured source code is better than any kind of comments.
= Data Model =
== 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).
Properties with different data types can be modeled for every entity, and one such MetaClass can inherit the properties from another (e.g., there could be a MetaClass "SAFETY_INSTRUCTIONS" inheriting the "Filepath" property from a "DOCUMENT" MetaClass).
== 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.
== 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.
But, worry not. {{UBIK}} is designed to provide views and transformations of a basic data model.
So, we can create an extension of the original data model in a second design phase, where we provide a model tailored to the (mobile) use-case.
This extension can happen on multiple levels:
* A new layer of MetaClasses can be used to perform calculations on and combine more basic data.
* A View can provide a custom hierarchy between instances using relations, queries and custom implementations of view-connections between objects (so-called ViewItems).
* A Scope can define how to display objects on the mobile application, allowing for a custom representation in the UI.
Also, {{UBIK}} comes with a lot of features one can apply to influence the behavior of (data on) the mobile client, ranging from inter-dependent tasks and work-packages to dynamic selective lists.
= Algorithm =
Most {{UBIK}} customizings introduce custom code performing more or less complex data processing tasks.
The algorithm resulting from custom code can be highly distributed because of the way the life cycle of {{UBIK}} objects can be customized.
But it can also be a single interface with a third party system that has to crawl through a lot of data and perform many operations on them.
In any case, it pays off to get a good idea of the virtual processes resulting from the customizing for multiple reasons:
* Algorithms can scale very badly if their time complexity is not considered.
* Especially distributed algorithms can misbehave seriously and are very hard to maintain if they are not understood thoroughly.
These two reasons should be sufficient to invest a substantial amount of effort into making the algorithm:
* Easy to understand
* Scale well with respect to more input
There are also some quick hints we can drop for you to avoid many problems:
* 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.
* 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.
* Avoid multi-threading, but if you have to implement parallel tasks, use locking wisely to avoid dead-locks.
* Check every variable for being null before you use it.
= Client UI =
For the client UI, it is important to consider some basic principle the client works by:
* 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.
* 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.
* 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.
<!-- DO NOT REMOVE THIS -->{{Template:HowTo/End}}<!-- DO NOT REMOVE THIS -->
==See also==
* [[HowTo:Organize_UBIK_Development]]
* [[Design_object-oriented_data_models]]
* [[Entity_Data_Model]]
* [[XAML]]
* [[Xamarin_XAML]]
* [[XAML_Basics]]
* [[XAML_Best_practices]]
[[Category:How-To|Design a Customizing]]
[[Category:Best Practices (internal)|Design a Customizing]]
[[Category:Resources (internal)|Design a Customizing]]