| Definition of the generic Data Type interface. This interface is a base interface,
which must be implemented by all datatypes in enterprise.
Every datatype must support two special states 'Empty' and 'Concealed'.
Empty instance is a typesafe way to pass around null values. Concealed
instance is a typesafe way to pass around data, which user in fact is not allowed to see.
Support for these states is realised by having following methods on every datatype class:
- public boolean isEmpty(). Returns true if this instance of datatype is empty.
- public static <Data Type> createEmpty(). Creates empty instance of the datatype.
- public boolean isConcealed(). Returns true if this instance of datatype is concealed.
- public static <Data Type> createConcealed(). Creates concealed instance of the datatype.
Note that concealed instance of datatype does not have any data inside, so even with debugger
it is impossible to see the content. This is achieved by having static creator of the concealed instance, which
makes it impossible for datatype implementor to forget to wipe out the content (alternative might have been
providing conceal() instance method, but this would rely on implementation to do the right thing and
wipe the data content out)
Every datatype can support unlimited number of application level methods (They are the reason
we have a datatype in a first place !). The methods generally fall into one of four categories :
-
Creators - methods used to create an instance of the datatype from raw data of some type.
Normally they are public static methods taking the raw data argument and returning an instance of the datatype.
Creators should always validate data and throw DataTypeValidationException in case of error.
One creator is mandatory : public static <Data Type> createFromString(String pString).
This creator is expected to create an instance from the person readable string representation.
-
Validators - methods used to validate proposed raw data of some type before creation can occur.
It is a good idea to have matching validator for each creator (and internally just call validator at the
beginning of the creator method) One validator is mandatory :
public static void validateString(String pString). This validator is expected to validate person readable string representation.
-
Getters - methods used to retrieve raw data of some type from instance. Notmally they are
instance methods taking no arguments and returning raw data type. It is a good idea to have matching
getter for each creator. One getter is mandatory : public String toString(). This getter
is expected to return person readable string representation.
-
Other - other method which retrive some values in some convenient form or perform
some data transformations (i.e Rectangle class may have public double getArea() method or
public void move(int x, int y) method ). These methods must be implemented in a way that they are able to deal with
empty and concealed states of the datatype - the least they should do is to throw appropriate exception.
See DataTypeInvalidOperationForConcealedInstanceException exception or
DataTypeInvalidOperationForEmptyInstanceException exception
for discussion on the best approach
Every datatype must implement either Serializable or Externalizable interface
(the reason this interface does not extend them, because we do not know which one !).
The Serialization/Externalization is the most native way for java to persist and transmit value objects
so this requirement is only natural.
In addition to serialization, every datatype must support other translation features such as
translations to/from java primitive type, to/from jdbc (java.sql.*) type and xml (org.w3c.dom.*) types.
This is achieved by each DataType providing access to DataTypeTranslationMetadata class, which in turn
has all details for applications to perform translation. This is realised by each DataType
having public static DataTypeTranslationMetadata getTranslationMetadata() method to support translation
features. See DataTypeTranslationMetadata class for details.
|