PackRuble / cardoteka

The best type-safe wrapper over SharedPreferences. ⭐ Why so? -> strongly typed cards for access to storage -> don't think about type, use get|set -> can work with nullable values -> callback based updates
https://t.me/+AkGV73kZi_Q1YTMy
Apache License 2.0
2 stars 0 forks source link

Watcher - mixin or field? #1

Closed PackRuble closed 7 months ago

PackRuble commented 1 year ago

We have to abandon the use of mixins to be able to make the class constant. Example - class Watcher We should probably use a simple composition.

→ If mixin: Pro:

Con:


→ If field (composition): Pro:

Con:


We could leave both ways, but an api that allows you to do the same thing in different ways is wrong in my opinion.

PackRuble commented 1 year ago

I'll have to figure out how to pass getOrNull(card) in the attach(...) method, because it's not available now.

Suppose we convert `WatcherImpl' like this:

class WatcherImpl implements Watcher {
  WatcherImpl(this.get);

  final _watchers = <Card, List<CbWatcher>>{};
  final T Function<T extends Object>(Card<T> card) get;

  // ... other methods
}
  1. Here we can no longer make our class a constant, since we store and change the state of _watchers.
  2. How do we pass the get method? It is needed so that when we call the attach method we return the actual value instead of card.defaultValue.

And here's the thing. Our `Cardoteka' now looks like this:

abstract class Cardoteka {
  Cardoteka({
    required Config config,
    Watcher? watcher,
  })  :
        _watcher = watcher,
        _config = config;

  final Watcher? _watcher;
}

Let's try to pass a parameter:

class UserStore extends Cardoteka {
  UserStore({super.watcher = Watcher(...), required super.config});
}

And at this step we encounter problem №1. We cannot pass a non-constant object as the default value.

If we try it this way:

class UserStore extends Cardoteka {
  UserStore({required super.watcher, required super.config});
}

main(){
  UserStore(
    config: ...,
    watcher: WatcherImpl(get), // get doesn't exist yet
  );
}

Then we cannot pass the get method because it belongs to an instance of a class that has not yet been created. The problem №2.


That's the kind of circular bail...

PackRuble commented 7 months ago

Which I've figured out at this point: