Skip to content

pragmatic-objects/oo-data

Repository files navigation

OO-Data

Build Status (Travis) Build status (AppVeyor) Codecov

Tool for generating data-like interfaces with basic structural subtyping support.

Quick start

  1. Add Maven dependency:
<dependency>
    <groupId>com.pragmaticobjects.oo.data</groupId>
    <artifactId>data-alltogether</artifactId>
    <version>0.0.0-SNAPSHOT</version>
</dependency>
  1. Describe your data by annotating package-info.java:
@Scalar(value = "UserName", type = String.class)
@Scalar(value = "UserAvatar", type = URI.class)
@Scalar(value = "UserLocation", type = String.class)
@Structure(value = "UserVisualInfo", has = {"UserName", "UserAvatar"})
@Structure(value = "UserContactInfo", has = {"UserName", "UserLocation"})
@Structure(value = "UserFullInfo", has = {"UserName", "UserAvatar", "UserLocation"})
package your.package.name;
  1. Build the project. OO-Data processes annotations on build phase and generates:
  • interfaces for your data: UserName, UserAvatar, UserLocation, UserVisualInfo, UserContactInfo, UserFullInfo
  • value objects: UserNameValue, UserAvatarValue, etc.
  • composite objects: UserVisualInfoComposite, UserContactInfoComposite, etc.
  1. Have fun

What sort of fun?

  1. Structures are always subtypes from scalars they have inside:
UserVisualInfo userInfo = ...;
UserName name = userInfo; // correct
UserAvatar avatar = userInfo; // correct
UserLocation loc = userInfo; // incorrect! Location is not visual information.
  1. You can substitute larger structures in places where smaller ones are required:
UserFullInfo userFullInfo = ...;
UserContactInfo info = userFullInfo; // full information includes contact information, it's okay
  1. You can compose structures from scalars and other structures:
// from separate scalars...
UserFullInfo info = new UserFullInfoComposite(
    new UserNameValue("Sergey Kapralov"),
    new UserAvatarValue(url),
    new UserLocation("Nizhniy Novgorod, Russia")
);
// Or even from other structures
UserVisualInfo visualInfo = new UserVisualInfoValue("Sergey Kapralov", avatarUrl);
UserContactInfo contactInfo = new UserContactInfo("Sergey Kapralov", "Nizhniy Novgorod, Russia");
UserFullInfo fullInfo = new UserFullInfoComposite(
    new UserNameValue("Kapralov Sergey"),
    visualInfo, // avatar will be taken from visualInfo
    contactInfo // location - from contactInfo
);
  1. More tricks to come later...