lundi 4 octobre 2021

Dart: Code design for interface to construct objects from HTTP requests

I'm trying to implement an abstract base class for objects that will be parsed from HTTP calls. The goals is to create a CachedFuture<T> class that, when accessed, makes an HTTP call to get the object and caches the result.

My inclination was to implement the classes as follows:

class HTTPGetable<T extends HTTPGetable<T>> {
  static Future<T> httpGet(int id);
}
class CachedFuture<T extends HTTPGetable<T>> {
   int _id;
   Future<T?>? _cachedResult;
   bool _has_already_made_request;

   CachedFuture({required int this._id});

   Future<T?> get() {
      if(this._cachedResult == null)
        try {
          this._cachedResult = T.httpGet(this._id);
        } except {
          // parse error or other error
          this._cachedResult = CompletableFuture.completedFuture(null);
        }       
      }
      return this._cachedResult;
  }
}

The intuition here is that there are a lot of objects with "pointers" to other objects in the database on the backend. It doesn't make sense to follow every pointer when constructing objects to return in the HttpRequest, so my intent is to wrap "pointers" in this CachedFuture class.

This should enable someone to "follow" one of these "pointers" without ever having to worry about caching the http request or about the specifics of constructing that request. Hopefully this provides another level of abstraction for the user of the class so they can right code that's agnostic to what's going on under the hood.

However, static interfaces aren't in Dart, so this pattern doesn't work. My intuition is that this is a sign I should be using a different pattern instead of trying to force my way.

httpGet is basically a factory method, but the functionality of CachedFuture needs a way to look up the factory from the type, so I don't immediately see a good way to implement a true factory either.

Could anyone recommend a good programming pattern for solving this? I imagine it's a pretty common usecase for both http requests and database requests.

Aucun commentaire:

Enregistrer un commentaire