State Graph Architecture – Reference Points

Experimental: Further advancing StateGraph Architecture, this delves into the referencing of data, as the app transitions states.

Applications are based upon interacting and recording data from the user or hardware events. In existing architectures, you would often group access to certain repositories and even sections of those repositories, into separate classes. As you collect the data, you will generate computed data from multiple sources, and finally generate UI specific data to render.

The result, is a number of classes containing source data, computed data and display data, across multiple layers of the app. If you have built an MVVM based application, you will recognize that this data gets spread across the Model, ViewModel, View, Service, Repository. Sharing becomes difficult, without breaching defined layers or abstractions and duplication starts to creep in. Finding raw data sources and/or similar computed data becomes tedious and is often missed.

Reference Points

Looking at data in a slightly different way, split each data reference into 3 categories of raw (aka repository), computed and display data.

 

While these can be placed into different classes or files to group them as you normally would, they just building blocks of data, from a single layer, not across multiple. This data is fed into your app state when you request.

Repository Reference Point

I will be using functional programming patterns here to keep every reference point function pure, as state is only contained in the StateGraph, and is not present anywhere else.

In this example I will go through an API call. At first we have the function to send an API request. This

typedef Response HttpSend(Request request);

Response send(Request request) {
  // Set Authentication here

  // Send request over http here

  // Return response - Example
  return Response("error", 404);
}

class Request {
  final String url;
  final String token;
  const Request(this.url, this.token);
}

class Response {
  final String data;  
  final int code;
  const Response(this.data, this.code);
}

class ApiState {
  final HttpSend send;
  final String token;
  const ApiState(this.send, this.token);
}

We have simple send function that sends a Request and gives us back a Response.

Next we implement an API endpoint call.

typedef bool LoginRequest(String username, String password);

class Account {
  static LoginRequest login(ApiState apiState) =>
      (username, password) => _login(apiState.send, apiState.token, username, password);

  static bool _login(
      HttpSend send, String token, String username, String password) {
    var request = Request("/v1/login", token);
    // Add in username and password to request

    var response = send(request);
    if (response.code == 200) {
      return true;
    } else {
      return false;
    }
  }
}

We have a number of things going on here.
1) The _login function accepts the actual function to send a Request, along with other data needed.

2) A LoginRequest typedef is created, to define the actual call parameter, specific to this request.

3) login is a Partial Function, that takes an ApiState, but then returns the LoginRequest, for the function to call.

In our StateGraph, we create a function that returns a particular state.

static ApiState apiState() => ApiState(send, "token");

Finally in our LoginNode, we have the function that will return the required State.

static IState login(
    LoginRequest loginRequest, String username, String password) {
  final result = loginRequest(username, password);

  if (result == false) {
    // Do some logic
    return LoginErrorState();
  }

  return DefaultLoginState();
}

In the Widget, via the onPressed event, you would call this function.

onPressed: () => StateGraph
            .apply(login(Account.login(StateGraph.apiState()), "username", "password")),

The StateGraph provides the state and combines with the input via the user, to be sent to pure functions mentioned.

Computed Reference Point

Computed reference points are only the combination of multiple other raw or computed data sources. You would create a pure function that has the inputs of 2 other functions.

Display Reference Point

A display reference point is actually just a Widget, and what I refer to as a node in the final part of my previous State Graph blog post.

Learn More

If you want to delve deeper, please see the StateGraph GitHub repository.

Mobile Developer, Microsoft & Xamarin MVP

Share on
© 2018 Adam Pedley