Skip to content
This repository was archived by the owner on Oct 3, 2024. It is now read-only.
Nils Brugger edited this page Aug 6, 2021 · 2 revisions

Explanation

To detect changes in an object the object has to be reactive. This ensures that we can display changes in this object. This is not a trivial task so there are drawbacks. In order to be convenient and counteract the drawbacks, we created many different forms of reactive objects so you can choose one for your applications. The functionality is the same for every approach.

A requirement for every single approach is encapsulation -> all fields/attributes are private.

If you are interested in how this was achieved: Technical details

Types

ReactiveObject

This approach is for everyone who dislikes runtime reflection magic. Using ReactiveObjects is the most "Vanilla" like aproach.

Example/Code

Class:

public class Properties extends ReactiveObject {
    private float volume;
    public void setVolume(float value){
         this.volume = volume;
         react();
    }
}

Instance:

Properties props = new Properties();

Pros & cons

Pro Con
No Runtime generated classes extend is needed therefore no other class can be derived from
You can define exactly when to update the ui (react call) You **
have** to define when to update the ui
You can use new ()/the constructor to create objects Will just update the UI if you call a setter

ProxySubject

(Most common/advised)

This approach is for everyone who thinks convenience over convention. This approach is low effort

Example/Code

Class:

public class Properties implements ProxySubject {
    private float volume;
    //setters & getters not needed
}

Instance Creation:

Properties props = ReactiveObject.create(Properties.class);

Live Object Wrapping:

Properties props = new Properties();
Properties reactiveProperties = ReactiveObject.wrap(props);

if Properties(String) is the only constuctor we need to pass a string to wrap the object. The value just needs to be valid there is no need of a "usefull". It just needs to pass the constructor without a IllegalArgumentException

Properties props = new Properties("Name of properties");
Properties reactiveProperties = ReactiveObject.wrap(props,"");

Pros & cons

Pro Con
Beside the instantiation you have no restrictions at all Uses Runtime generated classes
This design allows to extend from any class(more: inheritance) implementing an interface without "using" or implementing it is uncommon
You cannot use new to create instances of this class

ReactiveProxy

This approach is for everyone who doesn't likes that you can't affect when to update the UI with ProxySubjects

Example/Code

Class:

public class Properties {
    private float volume;
    //setters & getters not needed
}

Instance creaton :

ReactiveProxy<Properties> propsProx = ReactiveObject.create(Properties.class);
Properties props = propsProx.getObject();
propsProx.setStrategy(REACT_ON_SETTER);//(optional)

Live object wraping :

Properties props = new Properties();
Properties reactiveProperties = ReactiveObject.wrap(props);

if Properties(String) is the only constuctor we need to pass a string to wrap the object. The value just needs to be valid there is no need of a "usefull". It just needs to pass the constructor without a IllegalArgumentException

Properties props = new Properties("Name of properties");
ReactiveProxy<Properties> reactiveProperties = ReactiveObject.wrap(props,"");

Pros & cons

Pro Con
You can define all which methods cause a UI reaction Uses Runtime generated classes
This design allows to extend from any class(more: inheritance) Bulky instantiation
You end up with two objects that you need to keep both
You cannot use new to create instances of this class

Applications

This is most used if you want to use classes from a lib where you have no control over the classes to make them implement ProxySubject as this method works with any encapsulated class.


3rd Party classes

If you have no control over external classes you still want to display there are two mayor ways:

  1. Just use ReactiveProxie
  2. Create a ProxySubject layer

Whats a ProxySubject layer???

In the end it is just an empty class that derives from the class you want to use reactive.

@ReactivResolution(DEEP)
public ReactivePropertie extends ThirdPartyClass implements Reactive Subject {}

More info about @ReactivResolution see inheritance

Annotations

To make the configuring of this classes easy we created a few annotations


@Reactive

Fields/Attributes

Enables you to change the name of a variable for binding

@Reactive("vol");
private float volume;
binder.bind("vol",....);

Methods (unreleased v3.1.0b4)

Makes that calls to the annotated method trigger UI updates.
This will change the current functionality of ReactiveProxy#setStrategy(Strategy) and replace ReactiveProxy#reactTo(String...)

(deprecated) Methods

Acts as listener forward in ReactiveComponent and ReactiveView. This will be replaced by @ReactiveListener Examples in Components & Views


@ReactiveResolution

Used on class to define weither to just react to variables in the class itself, or to also make inherited field/attributes reactive.

@ReactivResolution(DEEP)
public ReactivePropertie extends ThirdPartyClass implements Reactive Subject {}