Developers Club geek daily blog

2 years, 11 months ago
 About kastomizatsii information systems

The main route of activity of our company ≈ is development of corporate information systems. Besides systems under the order we do two duplicated products. Certainly, we try, that our products were as much as possible convenient and functional. However in real life each business has the singularities and is not always ready to be reconciled with standard possibilities of system. There is a task of finishing of the solution under the specific client and its further support. What approaches to the organization of architecture of expansive products exist? What problems can originate by development? How we arrived? About all it more low.

Possible approaches


To begin with we specify that ²proektom-expansion ⌡ or it is simple ²rasshireniem ⌡ we name a product with the imported modifications for the specific customer. And now we consider some of possible approaches to the product extension:
Separate branch in a repository under each design-expansion
Perhaps, this thought ≈ first which comes to mind, after all to branch off from the main product and to make changes in new branch ≈ the most sweeping method to attain desirable result. A question only in the price which should be paid for this speed.

After development and information system implementation the long begins and is frequent the most painful phase of life cycle ≈ a support. In a case with the design-expansion this phase can become twice more unpleasant, after all it is necessary to deliver the customer not only new fichi √ which are implemented specially for it, but also new versions of a product on which the extension is based. That changes got to the design from the new version of a product, one method ≈ merge changes from the main branch in branch extensions sees. But present, how much it appears is labor-consuming, and how many potential errors can be manifested, if the same section of the code strongly changed in both branches.

It is possible to think at once, of course, of the future transfers into the new version of a product and to organize the code in such a manner that all specific changes will be allocated as much as possible away from the code of the main product. In the ideal world it would operate, but we live in a severe reality where often due date of the task can be declared as vchera √, and completely not compact command of class professionals, and a battalion of yesterday's students works over the design. In such situations people rarely reflect on architecture and go by the way of the least resistance ≈ found a place where it is necessary to correct, deleted old, wrote the new. It, by the way, conducts to one more big problem ≈ the logician of the extension mixes up with logic of a product.

The total: the given approach is the most floppy as allows to change any part of a product, but to rejoice flexibilities it is necessary only first to steam of updates. Afterwards huge complexities will be forwarded by a support of the extension and its transfer into new versions of a product. And than there will longer live an information system, especially and the support will become more labor-consuming.

Usage of dynamic attributes (model Entity-Attribute-Value)
Model Entity-Attribute-Value (or Open Schema) can be used together with standard relational model for dynamic determination and storage of values of new attributes of entities. At usage of model EAV of value of attributes are normally written to one table of three columns. As it is simple to guess, their names Entity, Attribute and Value:
  • Entity ≈ stores an object reference, which field we present. Normally it is the essence identifier;
  • Attribute ≈ the link to attribute determination (about it more low);
  • Value ≈ actually value of attribute.

Mandatory component of the circuit is also the table which stores the description of meta data for attributes:
  • attribute type;
  • restrictions (length of a field, a regular expression to which there should match value and so forth);
  • a component for representation in UI;
  • the order of representation of a component in UI.

For usage of this model in a product it is necessary to make 2 things:
  1. to Implement the mechanism of the job of meta data with which help we can to specify, for example, that to entities of type dogovor √ the new attribute ²data cancellation ⌡, field type ≈ ²data ⌡, a component for representation ≈ DateField will be added.
  2. to Implement mechanisms of representation and feeding into of values of dynamic attributes on necessary shields of a product. The mechanism should find a possible dial-up of attributes for the given essence in the table with the description of meta data, to represent components for their editing, and then in the table dataful to search and represent their values, saving them at shield closing.

The most important advantage of the approach ≈ this absence of necessity to create the design-expansion. The basic product is delivered the customer and at an adjustment or even maintenance stage any amount of dynamic attributes in entities is got.

Further about deficiencies. At first, it is boundedness of application. Model EAV allows to add only attributes in essence and to represent them in in advance certain place on the shield. No more that. About change of functionality, artful UI-components here speeches do not go.

Secondly, EAV the model creates the big extra charge on the DB server. For loading of one copy of essence without communications reading instead of one several lines of the table is required. For loading of the list of copies, for example in the table on UI, generally it is required N+1 requests, or dzhojny on number of columns of the table. Considering that the database in enterprise systems and so is the slowest and badly scalable element more often, such extra charge can simply kill system.

Thirdly, besides because of basis structure it will be difficult enough to do samplings of the data for reports ≈ instead of a spelling normal SQL for the relational data much more difficult requests be required.

Plaginnaja architecture
the Given architecture allows to store additional functionality in separate artifacts ≈ plug-ins. If your customer wants any new specificity you put to it a basic product, write a plug-in, connect it and is ready. For usage of plug-ins in a product extension points should be declared. What is it? If it is simple, it is certain places in the code. The loaded plug-ins in these parts get over, is analysed, whether there is in plug-ins a logic intended for the given point of the extension and if such logic is, it is fulfilled. Instances of points of the extension: menu item, obrabochik commands, the button on a toolbar, the new shield.

Such often used alternative of the extension of functionality as in exterior scripts, also it is possible to refer to the description of logic and event handlers to variations of plug-ins since scripts are caused and executed by certain points of the program.

The plaginnaja architecture allows to store all new functionality separately from a product that is its important advantage. The full physical sharing of a product and plug-ins does process of update of the version of a product or a plug-in very simple ≈ enough only to replace the updated component.

But also here, unfortunately, there are deficiencies. For any products they appear insignificant, for any can become the reason of impossibility of usage plaginnoj architectures. The matter is that the plug-in can expand system only in that place where the extension point is defined. Undoubtedly, there is a class-room of products where basically it is a little such places and all of them are in advance defined, but is as well huge group for which to foresee that it is required to expand tomorrow, it is almost impossible. The analysis of potential expansive places can become very much resursoemkim occupation in summary all the same to appear not absolutely exact. Besides,  extension points it is master code complication that is always fraught with errors and complexity of attending. To approach to determination of points of the extension in the main product it is necessary very thoughtfully.

As it is done by us


We released two duplicated products on the market: ECM (or in customarier terms, system of electronic document circulation, SED) the THESIS and system for automation of business of a taxi Sherlock . It was from the very beginning obvious: to deliver the specific client as much as possible convenient system, product finishings and therefore at the heart of a product easily expansive architecture should lie be required.

Beginning operation over the new extension, is frequent we at all did not assume, in what ²monstra ⌡ (in good sense of a word) this design can outgrow. The everyday occurrence ≈ when that began as small kastomizatsija, comes to an end with almost completely rewritten business processes and additional logic on a good few of shields. In addition the product can extend new functionality, quite sufficient for independent system. As an instance ≈ in the design-expansion the THESIS for the large distributed company there was an automation of activity of treasury, an estimation of overall performance of employees and some more uneasy units.

A variety of demands, their volume and unpredictability did not allow to use any of the methods presented above. In addition to everything, versions of products quit regularly enough. It does by the mandatory demand the maximum ease of transfer of the design-expansion on the new version of a product.

How we solve a problem of creation and a support of extensions?

Our design-expansion


The majority of designs of our company are created by means of platform CUBA. We already wrote about it in one of past papers . To fathom, how designs-expansions are organized, at first it is necessary to be knocked down with the device of the platform.

If it is short, CUBA ≈ it is a dial-up of units, each of which gives certain functionality:
  • cuba ≈ the application kernel, comprises all infrastructure, means for the business logic organization, visual component library, a safety subsystem and so forth
  • reports ≈ a subsystem of generation of reports
  • fts ≈ a full-text search subsystem
  • charts ≈ a subsystem of an output of charts
  • workflow ≈ a business process management subsystem
  • ccpayments ≈ a subsystem of operation with credit cards

Each subsystem can comprise persistent entities, shields and services with business logic.

At creation of the new design, dependences on those basic units of the platform which functionality is necessary register in its script of the assembly. After that, using entities, shields and services of the connected units, we start to implement the design. Physically platform units ≈ it jar files, and the design installed on the server ≈ normal Java the web application.

When it is necessary to expand an existing product on a platform, we arrive so: we create the new design, but in its script of the assembly we specify dependence any more from platform units, and from an expansive product. The product itself actually appears in a role of a platform for development.

 About kastomizatsii information systems
Now in the design-expansion it is possible to create new installations of the blast-furnace model, to present the new user interface as in the most normal design on platform CUBA. All functional of is lower-lying units on the former is accessible to the development engineer.

The most obvious advantage ≈ all new logic is stored in the separate design-expansion. Always it is possible to see, what exactly and when you wrote within the limits of the current extension. The approach in any way does not restrict the development engineer in type of new functionality as it do plaginnaja architecture and EAV.

Extension translation process on the new version of a product consists in the following:
  • you specify the new version of a product in scripts of the assembly and peresobiraete the extension;
  • if in the extension it was used only stable API a product on it all ≈ launch the expanded product and forward;
  • if in a product there were the considerable changes in those points with which you expanded change of the code of the extension can be demanded. As a rule, it happens infrequently, and to localize a problem simply. Bagfiks-releases of products always save compatibility with extensions.

It is clear that in the extension it is easily possible to create new entities, business logic and shields for them. But how to change what already is available in a product? For example to add a field in grocery essence and to represent it in available shields?

Adding of new attribute in essence of a basic product


Let's define for themselves the task: in essence User a basic product it is necessary to add a field for address storage. Similar demands, perhaps, the most widespread among our customers. At once we tell that the platform supports model of dynamic attributes about which it was written above, but in practice this alternative is used rarely ≈ speed of sampling of the data and ease of creation of reports practically always appear the important demand.
Actually about an alternative method of adding of attribute. In the capacity of ORM by a platform it is used OpenJPA. The essence declaration in a product looks as follows:

 @E ntity (name = "product$User")
@Table (name = "PRODUCT_USER")
public class User extends StandardEntity {
	@Column (name = "LOGIN")
	protected String login;

	@Column (name = "PASSWORD")
	protected String password;

	//getters and setters
}
 

As you can see, this standard for JPA the description of essence and mappinga on the table and DB columns.

We create the successor of essence in the design-expansion:

 @E ntity (name = "ext$User")
@Extends (User.class)
public class ExtUser extends User {
    
    @Column (name = "ADDRESS", length = 100)
    private String address;

    public String getAddress () {
        return address;
    }

    public void setAddress (String address) {
        this.address = address;
    }
}
 

The inheritance mechanism is standard for OpenJPA except for the abstract @E xtends which represents the greatest interest. She declares that the class-room ExtUser will be used everywhere instead of class-room User.

Now all operations of creation of essence User will create a copy of the expanded essence:

  User user = metadata.create (User.class);//creates class-room ExtUser
 

Operations of extraction of the data from a DB also return copies of new essence. For example, in a basic product service of search of users by name, returning result following JPQL request is declared:

  select u from product$User u where u.name =:name
 

Without the abstract @E xtends we would have on an output a collection of installations User , and for obtaining of the address from ExtUser it should to re-read repeatedly from basis result of the previous request. But using the information on redefinition which is given by the abstract @E xtends , platform mechanisms produce preliminary conversion of request and return us a collection of installations of the expanded essence ExtUser . Moreover, if any other entities had references on User at extension connection these links will return installations of type ExtUser , without any change of the source code.

The essence is redefined. Now well to represent a new field to the user.

The platform shield represents sheaf XML + Java. XML it is declarative presents UI, the Java-controler defines response to events. It is clear that with redefinition of the Java-controler of special problems does not originate, and here with XML extension it is hardly more difficult. We return to the previous instance with field adding address to essence User .
Markup declaration of the elementary shield looks so:

 <wi ndow
        datasource = "userDs"
        caption = "msg://caption"
        class = "com.haulmont.cuba.gui.app.security.user.edit. UserEditor"
        messagesPack = "com.haulmont.cuba.gui.app.security.user.edit"
        >

    < dsContext>
        < datasource
                id = "userDs"
                class = "com.haulmont.cuba.security.entity. User"
                view = "user.edit" >
           </datasource>
    </dsContext>

    < layout spacing = "true" >
        < fieldGroup id = "fieldGroup" datasource = "userDs" >
            < column width = "250px" >
                < field id = "login" />
                < field id = "password" />
            </column>
        </fieldGroup>
      
        < iframe id = "windowActions" screen = "editWindowActions" />
    </layout>
</window>
 

We see the link to shield UserEditor control unit, the declaration of a source of the data (datasource), a component fieldGroup, a representing field of essence, and the frame with standard acts ok √ and otmena √ (windowActions).

It would not be desirable to double the code of the basic shield in the design-expansion at all, therefore we added possibility of inheritance of XML-descriptors of shields in a platform. Here so the successor of the shield from the basic design looks:

 <wi ndow extends = "/com/haulmont/cuba/gui/app/security/user/edit/user-edit.xml" >
    <layout>
        < fieldGroup id = "fieldGroup" >
            < column>
                < field id = "address" />
            </column>
        </fieldGroup>
    </layout>
</window>
 

In the shield-successor the ancestor (attribute extends) is underlined and those components which should be added in the basic shield are presented only or redefined in it. It is necessary to declare only the shield in a configuration file with the identifier of the basic shield:

 <scree n id = "sec$User.edit" template = "com/sample/sales/gui/extuser/extuser-edit.xml" />
 

Result:

 About kastomizatsii information systems

business logic Redefinition


As to functionality redefinition here all is trivial enough. The platform infrastructure is implemented on Spring. Accordingly and the layer of services about business by logic ≈ is controlled springom bins. The possibilities of the extension given frejmvorkom, it appears more than enough for redefinition of the necessary business logic. Visually to show it, again a small instance. We admit, on center in a basic product there is a component fulfilling calculation of the price:

 @Ma nagedBean ("product_PriceCalculator")
public class PriceCalculator {
	public void BigDecimal calculatePrice () { 
		//price calculation
	}
}
 

That in the design-expansion to replace algorithm of calculation of the price we do 2 simpl steps:

We create the successor of a redefined component:

  public class ExtPriceCalculator extends PriceCalcuator {
	@Override
	public void BigDecimal calculatePrice () { 
               //modified logic goes here
	}
}
 

We display the class-room in configuration file Spring with the identifier of a bin from a basic product:

 <bea n id = "product_PriceCalculator" class = "com.sample.extension.core. ExtPriceCalculator" />
 

Now container Spring will always return us copy ExtPriceCalculator.

subject Redefinition


With modification of entities, components of shields and business logics we were knocked down. A visual subject following on queue.

The shields created by means of a platform, work in a web and a desktop clients. By the current moment at us usage of web clients predominates, therefore telling about kastomizatsii subjects, we consider them.

For implementation the web-UI us has been selected popular frejmvork Vaadin. Vaadin allows to present subjects on SCSS. The description of styles for a new subject on SCSS in itself in times is more sweet, than on pure CSS. We made process of creation of a subject by even less labor-consuming, carrying out assemblage of parameters in variables.

Preparation for a new subject forms in 2 clique by means of our studio of development. The new subject imports styles of a basic subject of a platform, the development engineer needs to redefine only necessary styles and variables. Many clients wish to see an information system in corporate colors of the company. The approach used by us to the extension that allows them to achieve easier it.

In the design the extension possibility of connection of new visual components is accessible to the development engineer. A considerable quantity of ready components is available in a repository addonov Vaadin. If the necessary component there was not, it is possible to write him.

Instances of various visual subjects:

 About kastomizatsii information systems

 About kastomizatsii information systems

the Inference


If our approach seemed to you interesting can try a platform CUBA . Creating a product on a platform, you have automatically an opportunity kastomizirovat its presented method. Are always glad to responses and comments!

P.S. The author of a capital photo ≈ Ilya Varlamov. Even more smart Pakistan trucks you can find in it a blog .

This article is a translation of the original post at habrahabr.ru/post/214787/
If you have any questions regarding the material covered in the article above, please, contact the original author of the post.
If you have any complaints about this article or you want this article to be deleted, please, drop an email here: sysmagazine.com@gmail.com.

We believe that the knowledge, which is available at the most popular Russian IT blog habrahabr.ru, should be accessed by everyone, even though it is poorly translated.
Shared knowledge makes the world better.
Best wishes.

comments powered by Disqus