OpenHFT / Chronicle-Wire

A Low Garbage Java Serialisation Library that supports multiple formats
http://chronicle.software
Apache License 2.0
513 stars 123 forks source link

Introduce Managers for data carriers (such as Marshallable and records) #227

Open minborg opened 4 years ago

minborg commented 4 years ago

Problem Description

There are several drawbacks with the current solution where data carriers are responsible for their own management:

image

Proposed Solution

Therefore, I propose that we decouple the data carrier from the logic that creates and accesses the data carrier. Thus, creating single responsibilities for these types of classes:

Manager Example

Here is an outline of a Manager skeleton:

public interface Manager<T> {

    T fromFile(String filename) throws IOException;

    void writeMarshallable(T t, @NotNull WireOut wire);

    T readMarshallable(@NotNull WireIn wire);

    void readMarshallable(T using, @NotNull WireIn wire);

    <R> R getField(T target, String name, Class<T> tClass);

    void reset(T t);

    static <T> Manager<T> create(@NotNull final Class<T> clazz) {
        return new VanillaManager<>(clazz);
    }

}

Methods could be grouped by means of methods like marshaller() that exposes all the marshaling methods or by creating distinct sub-interfaces that hold related methods together (e.g. Marshaller<T>).

User code Examples

Legacy classes

// The class HyperBankDay is already defined in a separate existing library
Manager<HyperBankDay> dayManager = Manager.create(HyperBankDay.class);

// Read a Day from the provided wire
HyperBankDay lastDay = dayManager.readMarshallable(wire);

Modern Java

// Define the data carrier
record Day(long id, float opening, float last, float min, float max, float closing) { };

// Create a Manager
Manager<Day> dayManager = Manager.create(Day.class);

// Creates a new immutable Day from the provided wire
Day lastDay = dayManager.readMarshallable(wire);

Creating Managers

Manager implementations can be created in many ways. For example, Managers could be created using reflection (as shown above), using builders or they can be generated.

Migration

Once implemented, the end-user code could be migrated at that time, later or never. Thus, older code will continue to run unaffected.

dpisklov commented 4 years ago

I suggest using more standard term DTO (data transfer object) as opposed to "data carrier" - it also then suggests a standard term for "Managers" - DAO (data access object).

peter-lawrey commented 3 years ago

This is a major change, suitable for when we re-write for Java 17.