ADAM features |
ACommon library is a standalone set of various utility packages, and ADAM frameworks depend upon only several classes from those packages.
ADM featuresInterfaces of Data objects and their transient implementationsThis basic framework of ADAM project follows nonstandard ("generic") approach for manipulating objects: 1) for all entity types, only one object class is used, and it isn't defined in the application (that is much simpler than multitude of application-dependent business object classes); 2) each object (called Data) presents a set of named properties (fields) rather than being POJO, JavaBean or EJB-like component. Fields can be accessed by name with getters (defined in Data interface) and setters (defined in MutableData interface). Getters/setters exist for all common data types: boolean, int, double, String, Data (object), DataSet (set of objects). Data also has type (String) so that Data with the same type have the same names and types of their fields. Sometimes Data type is used to access Data-type or DataSet-type field of parent Data (TypedFieldData); this is useful when Data present persistent object and values of its fields can be swizzled from some storage. MutableComparableData interface (both Data and MutableData) is enough to store data in memory but in typical applications with UI it is usually wrapped by DataWrapper interface. DataWrapper has ID (int) and ability to change according to another MutableComparableData (it's useful when the process of editing data in some UI form is complete). There are several implementations of Data (MutableComparableData) – implementations based on arrays (array of field names and field values), on a map, on reflecting fields of POJO (although the last variant can be recommended only in order to extend some legacy applications: the time of response to changes is lower for business objects than for pure ADM Data). The superclass of all implementations (AbstractData) has the most interface methods implemented (e.g. it casts field values and perform corrects comparison/copying of the object) so you can easily extend AbstractData to adapt your own data structure to Data interface [mipt.data.impl]. There is also an alternative part of the framework that have the same purpose but accesses fields by its number/index (instead of name); it is more efficient in array-based implementations but much less convenient for a programmer so this alternative is not recommended [mipt.data.indexed] Collections and factories of Data objectsCollections are presented by interfaces *DataSet (set of Data), DataList (indexed list of Data), Data*Finder (searchers for one or several Data by field values) [mipt.data] and their implementations based on arrays and trees [mipt.data.impl]. This part of ADM framework is often optional because it addresses the same problems which can be solved by a client programmer using Java Collections Framework since version 1.5 (when ADM was developing in 2000 there were no generic types in Java). Note that all Data collections in [mipt.data.impl] implement both “indexed fields” and “named fields” interfaces. DataFactory interface [mipt.data] is useful to abstract application from concrete class of data to be created in it (DataFactory is usually injected to the main part of the application). The interface has 7 implementations [mipt.data.impl] which not only differ by the class of creating Data but create Data with either one or various types. Simple implementation of Data persistencyADM framework contains only transient data models (no DB-oriented concepts of connections, resource pools, transactions, etc. are introduced here) but it has several persistent Data classes loadable from XML data source by means of JDOM library. The structure of XML is much more compact and human readable than XML serialization in Java. [mipt.data.xml] Models and controllers for application parts based on MVC[mipt.data.event] contains events with Data object or a list of such objects, appropriate listeners and event sources (including DefaultDataModel that can be viewed as wrapper for one Data and as MutableData with notification of listeners in setters). Conversion between DataModelEvents and mipt.io.sync.ObjectEvents is also supported. [mipt.data.choice] is a framework with interfaces and abstract implementations for managing data in UI components (“choices”) like lists, trees, tables where Data objects can be selected, added, removed, changed, etc. [mipt.data.choice.event] is a part of the framework that is closely connected with events (event listeners, event sources, notifying parts of event sources). ADMStore features
ADMStore framework is aimed at minimization of time spent on developing relatively simple applications – as it does not require neither coding/generation of data-access classes nor configuration of object-relational mapping (that is always presented e.g. as XML in various ORM frameworks or as annotations in JPA). On the other hand, ADMStore is very efficient for research purposes as it enables correct comparison of completely different data access technologies and even different data storage approaches (plane tables of relational DB, object meta-models stored in RDB, object-oriented DB, multi-dimensional and key/value approaches). The last feature is due to universal program definitions of query conditions (i.e. definitions represented by objects) instead of technology-dependent text definitions (like expressions in SQL, JPAQL or EJBQL languages). The “price” of the universality mentioned is high enough: the search capabilities are strongly restricted by ADMStore interfaces (ADMStore defines only frequently used searches which are common to all or at least many approaches; and it would be almost impossible to repeat all capabilities of all query languages). But that “price” is fully acceptable for research applications – even for researches on data access technologies and data storage approaches (e.g. for query performance researches or for investigations of efforts required from application developers). Moreover, some features of ADMStore allow profound investigation of object caching and field caching models. Being the persistent extension of transient ADM framework, ADMStore defines the stored object interface (PersistentData from [mipt.data.store]) as a typed set of named properties (fields) rather than as POJO, JavaBean or EJB-like component. Such an interface is often referred to as Generic Persistent Object. Like any other persistent object, PersistentData object has an identifier (of any type, implementing DataID interface) and can be deleted, saved and changed (“changing” here means setting a field followed by immediate saving of the object). That work of the object is almost always delegated to DataStorage (from [mipt.data.store.table]). Objects can be loaded by PersistentDataFinder (with basic capabilities to search objects of one type by e.g. a given value of one field) and by ExtendedDataFinder (multiple criteria and ordering attributes, hierarchal queries, joins i.e. value selection from objects of multiple types; [mipt.data.store.search]). DataFinders and DataStorage extend the same DataTable interface with a reference to EntityMetaData – meta-information about the structure of one entity. All kinds of DataTables are created and cached by corresponding DataTableFactories ([mipt.data.store.table.factory]). Only plane RDB implementation supports all ADMStore interfaces and is ready to use. It is based on AStore framework that in turn has full RDB implementation based on ARDB library (and has non-full implementation based on the text symbol-separated files). Several up-to-date implementations of ADMStore framework are now under development. They include meta-model approach (also using RDB in the low level) and key-value approach (based on Project Voldemort). Implementations of OODB and multidimensional approaches (both with Caché database) are also planned There is an isolated sub-framework ([mipt.data.store.subclass]) for those developers who got used to the standard concept of a business object (a class with fields corresponding to a table with attributes in some database). Existing finders and storages of business objects delegate their work to the DataTables from [mipt.data.store.table]. There also exists a generator of Java source code from RDB tables’ definitions, and the business objects generated use some PersistentData implementation to access fields. Unlike generic persistent objects above, this subframework can not compete with a multitude of other data access frameworks like Hibernate or iBATIS. [mipt.data.store.event.*] packages are also worth mentioning; they contain events, listeners and other classes for synchronizing states of multiple data storage instances. They are fully compatible with [mipt.io.sync] package from ACommon library so that one can easily configure the synchronization of multiple instances of standalone applications caching their data (“thick clients”). Thick clients’ synchronization can be treated as one more experimental approach to information systems introduced in ADMStore (contrary to the features mentioned above, this one is efficient only for applications with small number of concurrent users, with computational or analytical systems being examples).
AStore features
[mipt.io.table] and [mipt.io.table.indexed] are similar frameworks for non-object access to any data storage (writing, reading, complicated search). Methods of *Table interfaces of both frameworks return/accept arrays of objects – values of table cells. And Tables are created and cached by Factories ([mipt.io.table.factory], [mipt.io.table.indexed.factory]). The main difference consists in the way of identifying table columns and rows: column names and row criteria are used in [mipt.io.table] whereas column indices and row identifiers (of long type) are used in [mipt.io.table.indexed]. For a client, the first way is more convenient but the last way is much faster, and the speed of access will remain higher after wrapping of [mipt.io.table.indexed] by some object access framework like ADMStore (in comparison with wrapping of [mipt.io.table]). That is why both frameworks are usually implemented simultaneously (for a client and for a wrapper framework). Implementations exist for a relational database (with the help of ARDB library; [mipt.io.table.rdb]) and for plane text files (symbol-separated files; [mipt.io.table.text.file]). The last one is convenient when a client program must work without any installation/configuration; but complicated search is not supported in this case. [mipt.search.analytic] and [mipt.io.table.analytic] packages contain interfaces and data structures defining analytic queries – for example, aggregations (which are implemented as GROUP BY clause in a relational DB) – without any text representation. But till now, there is no support of this functionality neither in AStore nor in other projects yet.
ARDB features
[mipt.rdb] is a library for simplified access to a relational database (with caching typical DML and DQL queries, with support for LOBs and stored procedures/functions). Two-way data type conversion (as well as new identifier query, etc.) is delegated to DBMS-specific agent (Oracle, MySQL and others are now supported). ARDB itself is not recommended for serious applications because it is just a convenient wrapper of JDBC but it does not support features typically required by enterprise applications (for example, object data models). Nevertheless ARDB can be useful in higher-level data access frameworks to avoid a large portion of routine work. Note: [mipt.rdbms] is absolutely deprecated because it has very low cohesion: its Table and Connect classes are responsible for too many different aspects (and the abstraction of data access interface from RDB implementation is absent as well); see AStore framework to avoid those design drawbacks.
|
|||
Last Updated on Saturday, 26 June 2010 06:56 |