Wednesday, June 30, 2010

mShop - The object classes

It's been a while since I wrote my last post about the mshop application. Today I would like to present the
data structure which is visible to the application user and offers him the ability to model his problem domain
as best as possible.

As I have stated in my last article, most applications leave you with a rather inflexible data structure which
requires you either to adopt your problem domain to the software system or modify the software system in its
core parts to support your problem domain. Neither way is an acceptable solution to your problem.

When I started to design the mshop application, I had in mind that establishing a kind of a centralized order process
within a company must adhere to the fact that the users are not willing to use one service for ordering objects
of type A (like user accounts) and another service for ordering objects of type B (like computers or other office
supplies). Beside that the whole workflow based approval process needs to be independent from the concrete object
types handled by the system.

Therefore I tried to define a very generic data structure and a highly flexible approval engine. Both elements
will be presented more detailed in the following paragraphs.

Data structure


The data structure basically follows the object oriented design techniques used for software component specification. The following types are provided


  • attributes

  • attribute types (like integer, date ...)

  • classes

  • objects (as class instances)



A class is composed of an arbitrary number of attributes which have a specific type which could be a


  • INTEGER

  • DECIMAL

  • STRING

  • TIMESTAMP

  • BOOLEAN

  • BLOB

  • OBJECT_REFERENCE

  • CUSTOM_TABLE_REFERENCE



Most of these types are self-explanatory except OBJECT_REFERENCE and CUSTOM_TABLE_REFERENCE. An attribute
of type OBJECT_REFERENCE is allowed not to hold a value but a reference to another object (eg. a user references
another user to model the supervisor relationship). This gives the user the maximum power to model complex relationships.

The other special type (CUSTOM_TABLE_REFERENCE) has been implemented but is not in use. The idea behind this attribute type is the ability to reference objects or values that are completely unknown to the application and must not be modeled
within the domain. Actually this is just an extension point that might be used in the future.

When an attribute is assigned to a class, the user needs to specify some attribute values of this relationship


  • NAME - name of the attribute (eg. firstname, lastname, email, ...)

  • DESCRIPTION

  • MIN_TIMES - defines how many values must be assigned to this at minimum (used for list modeling)

  • MAX_TIMES - defines how many values can be assigned to this at maximum (used for list modeling)

  • REQUIRED - a value for this attribute must be provided

  • VISIBILITY - defines the visibility of this attribute (public, protected, private - read more down below)

  • ATTRIBUTE_TYPE - defines the attribute type (eg. INTEGER, DECIMAL, STRING, ...)



The VISIBILITY of an attribute defines the scope within the attribute is visible to any accessor. If the attribute
is marked to be PRIVATE only the class or instance is allowed to read and write values from / to it. If the attribute is
marked to be PROTECTED the class or instance and all ancestors and its instances of the defining class are allowed
to read and write values from / to it. If the attribute is marked to be PUBLIC all classes and instances are allowed to
read and write values from / to it.

Although there are no limitations concerning the depth of a class hierarchy and the number of attributes within it, the user
must be aware that each new level has an impact on the overall performance of the current hierarchy.

After having defined the classes the application allows to create instances (objects) from these blueprints. Therefore the application reads the class definition (including all ancestors) and provides the user with a dialog that requires him to provide values for all attributes visible to him.

Approval engine

The job of the approval engine is to analyze incoming object orders using a XPath like expression language and forward them to a suitable set of approvers (might be a single one as well). If a required number of users have approved the order it will be either forwarded for final processing (like creating user accounts or ordering printers) or - if required - forwarded to another set of approvers (two men rule). This depends on approval information provided for the underlying class.

Each class can have one or a whole set of approval information where each element defines how entities must be handled that apply to the given path expressions:


  • OBJECT_CLASS - defines the class that this element provides approval information for

  • AUDIT_LEVEL - defines the audit level (1..n, two men rule)

  • DISABLED - the element will not be used by the approval engine

  • ORDER_CREATE_ALLOWED - if an object applies to the given path expressions, it might be created

  • ORDER_UPDATE_ALLOWED - if an object applies to the given path expressions, it might be updated

  • ORDER_DELETE_ALLOWED - if an object applies to the given path expressions, it might be deleted

  • PATH_EXPRESSIONS - set of strings holding path expressions. if any object positively evaluates against all of these expressions, the options mentioned above will be applied



The approval engine reads the type of an incoming object order and fetches all approval information entities for that type. All path expressions of each entity are evaluated against the object. If any of them fits, the rules defined by the associated approval information entity will be used by the engine on how to further process the object order (eg. which audit level it requires, if an object might be
created at all).

Now the engine finally needs to identify all possible approvers for the ordered object. Therefore a quite similar information entity is used. If differs from the one above only by adding the following attribute


  • PRIORITY_LEVEL


The PRIORITY_LEVEL is used by the approval engine in case the current set of approvers did not respond within a given timespan. Now the engine needs to forward the order element to a second/third/fourth ... round of approvers where the priority level identifies the specific round when an approver enters the ring.

Before the engine forwards an order to an approver it uses the path expression set to evaluate if the ordered object can be handled by a specific approver. If the path expressions are all valid, the engine checks if the operation (create, update, delete) might be carried out the by approver at all.

Conclusion

Although I just provided you with only a small view, I guess you got a good hint on how flexible the application's data structure is. In the upcoming articles I will talk a bit about the license model of mshop and provide you with some screenshots and more information about key features.