OpenFuture

Pattern Name

Master Data Management

Intent

The Master Data Management pattern describes a generic solution for the problem of language-dependent information within a domain model.

In relational databases master data are often held in special look-up tables, which are joined together when a domain model is built up from a database. In many cases these language-dependent data are provided to the object model as integral part ot it. Dynamic switching the language at runtime requires a difficulat transaction to replace these language-dependent parts with new textual descriptions for the new language. Potentially the whole domain model has to be updated with the database and reloaded.

The Master Data Management pattern no describes a solution, which can enable your application to switch the language dynamically without difficult database transactions.

See the Download Section for a reference implementation and the source of the example.

Also Known As

Base Data, language dependent data, (German: Stammdaten)

Motivation

The figure illustrates the proposed solution for dynamic language switching: The domain model only refers to the Master Data objects by their object ID, which in many cases may be simply the foreign key to the relational database table for the Master Data. The Master Data Provider acts as broker for the required language-dependent data: It retrieves and manages them from the system and provides the matching Master Data object for the required type, ID and language.

Connecting domain objects to Master Data

Figure 1: Connecting domain objects to Master Data
 

For Example: In an application from the Automotive sector a Vehicle object is edited. It holds several data like a licence plate, chassis number, power data, which are language independent, and language dependent information as e.g. the Paint. To be able to switch the client language while the Vehicle is edited, the Paint object is made a language dependent Master Data object. The Vehicle object just holds the paintId of the assigned Paint object, the application requests a Paint object for this ID and the current language from the Master Data Provider at runtime e.g. to display the paint color of the Vehicle at runtime or allow the user to select a Paint from a list.

Example: Vehicle and Paint Master Data

Figure 2: Example: Vehicle and Paint Master Data
 

Structure

The responsibility for Master Data Management is distributed into three tiers:

Strucuture of the Master Data pattern

Figure 3: Strucuture of the Master Data pattern
 

Participants

Application

Master Data

Master Data Provider

Master Data Service

Master Data Source

Master Data Container

Collaborations

The following sequence diagram illustrates a simple example for the collaboration of the different participants of the Master Data Management.

Master Data sequence diagram

Figure 4: Master Data sequence diagram
 

The diagrams displays five sequential processing steps:

  1. At server start-up the Master Data Service is initialized by its initialize() method. In this method the service retrieves Master Data for all types and languages from its Master Data Sources.
  2. When the Application requests Master Data from the Master Data Provider the first time, it realises, that no data for the required language (here: a default language from the default Locale) are available for the given type. The fetchMasterData() of the provider retrieves them from the service, stores them in its cache and passes them back to the Application.
  3. Next time the Application requests the same data, the provider can simply provide them to the Application from its cache.
  4. At runtime the language of the Application's user interface may be changed.
  5. When the Application next time requests Master Data from the Master Data Provider, it realises, that the stored data don't match the provider's language any longer and it retrieves a new set of Master Data for the new language from the Master Data Service.

Implementation

The following class diagram illustrates the structure of the reference implementation. For all required participants in the Master Data Management an interface and at least one default implementation is provided.

Master Data class diagram

Figure 5: Master Data class diagram
 

  1. Domain Classes. The two general Master Data classes MasterData and LDMasterData implement the interface IMasterData. The class LDMasterData, the language dependent version, implements the interface ILanguageDependent.
  2. Master Data Provider. The reference implementation illustrates a simple implementation of the IMasterDataProvider interface with the class DefaultMasterDataProvider. This class provides all functionality required including a mechanism to cache Master Data (one set per type). To implement a different caching mechanism, to provide direct access to Master Data for a certain type (see example) or to connect the provider to a Master Data Service at start-up its methods may be overwritten, additional methods may be added in a concrete subclass.
  3. Master Data Service. The reference implementation illustrates a simple implementation of the IMasterDataService interface with the class DefaultMasterDataService. This class provides all functionality to cache Master Data and to access them from a Master Data Provider. You can distribute the Master Data Service on your server and make it available for the client by a proxy, implementing the same IMasterDataService interface and encapsulating the communication to the remote service. Concrete subclasses overwrite the initialize() method to initialize the service at start-up with Master Data from the various Master Data Sources (see example).
  4. Master Data Source. The interface IMasterDataSource has to be implemented by concrete classes within the application, which can retrieve Master Data from various types of sources: files, databases, hot interfaces etc. The example illustrates a very simple way to create some Master Data.
  5. Master Data Container. The reference implementation provides containers for language-dependent and language-independent Master Data.

Sample Code and Usage

Master Data:

public class Paint extends LDMasterData {
   /** Field color (Color) is used to identify the Color value of the Master Data object */
   private Color color;
   /**
    * Constructor
    */
   public Paint(String id, String language, String text, Color color) {
	super(id, language, text);
	setColor(color);
   }
}

Master Data Provider:

public class MyMasterDataProvider extends DefaultMasterDataProvider {
   /**
    * Constructor
    */
   public MyMasterDataProvider() {
	super();
	setService(new MyMasterDataService());
   }
   /**
    * Insert the method's description here.
    */
   public Paint getPaint(String id) {
	return (Paint) getMasterData("Paint", id);
   }
   /**
    * Insert the method's description here.
    */
   public Vector getPaints() {
	return getMasterData("Paint");
   }
}

Master Data Service:

public class MyMasterDataService extends DefaultMasterDataService {
   /**
    * Initialize the Master Data cache
    * This subclass is a simple exampe how master data can be initialized.
    */
   public void initialize() {
	super.initialize();
	addMasterDataContainer("Paint", new PaintDataSource().getMasterData("Paint"));
	...
   }
}

Master Data Source:

public class PaintDataSource implements IMasterDataSource {
   /**
    * Provide some instances of Paint as simple example
    */
   public IMasterDataContainer getMasterData(String type) {
	Vector v = new Vector();
	v.addElement(new Paint("ff0000", "de" , "rot", Color.red));
	v.addElement(new Paint("00ff00", "de" , "grün", Color.green));
	v.addElement(new Paint("0000ff", "de" , "blau", Color.blue));
	v.addElement(new Paint("000000", "de" , "schwarz", Color.black));
	v.addElement(new Paint("ffffff", "de" , "weiß", Color.white));
	v.addElement(new Paint("7f7f7f", "de" , "grau", Color.gray));
		
	v.addElement(new Paint("ff0000", "en" , "red", Color.red));
	v.addElement(new Paint("00ff00", "en" , "green", Color.green));
	v.addElement(new Paint("0000ff", "en" , "blue", Color.blue));
	v.addElement(new Paint("000000", "en" , "black", Color.black));
	v.addElement(new Paint("ffffff", "en" , "white", Color.white));
	v.addElement(new Paint("7f7f7f", "en" , "gray", Color.gray));
		
	v.addElement(new Paint("ff0000", "fr" , "rouge", Color.red));
	v.addElement(new Paint("00ff00", "fr" , "vert", Color.green));
	v.addElement(new Paint("0000ff", "fr" , "bleue", Color.blue));
	v.addElement(new Paint("000000", "fr" , "noir", Color.black));
	v.addElement(new Paint("ffffff", "fr" , "blanc", Color.white));
	v.addElement(new Paint("7f7f7f", "fr" , "gris", Color.gray));
	
	return new LDMasterDataContainer(v);
   }
}

Known Uses

A similar implementation was elaborated to manage Master Data in a distributed used car management system.

Related Patterns

None.

Download

Download the reference implementation and the source of the example here!

The package openfuture.masterdata and all its sub-packages and extensions is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the

Free Software Foundation, Inc.,
59 Temple Place,
Suite 330, Boston,
MA 02111-1307
USA

Or visit http://www.gnu.org/copyleft/lesser.html.

Changes

0.1

Creation

1.0

First release of the component

1.2

"History tag in package description added

1.3

Resource Bundle MD Source and Localized MD Container added


Author: Markus Giebeler
Last Update: 19.01.2001 - 15:49