Hey!
If I want to control access to a regular class property, I implement a getter and setter for it. However, sometimes I have a class which exposes a collection of elements through a property (in my example, `Basket.items`):
class Item {
Basket basket;
String name;
Item(this.basket, this.name);
}
class Basket {
final Map<String, Item> items = {};
void doStuffWithItems() { ... }
}
Let's say I want to create items on demand, and enforce relational integrity between items and baskets; I can achieve this by wrapping `Item.basket` with getters and setters, and implement explicit `Basket.getItem` and `Basket.addItem` methods:
class Item {
Basket _basket;
String name;
Basket get basket => _basket;
void set basket(Basket basket) {
_basket._items.remove(name);
basket._items[name] = this;
_basket = basket;
}
Item._(this._basket, this.name);
}
class Basket {
final Map<String, Item> _items = {};
Item getItem(String name) =>
_items.putIfAbsent(name, () => new Item._(this, name));
void addItem(Item item) => item.basket = this;
...
}
This works, but the `getItem` and `setItem` methods feel inelegant and not Dart-y.
Also, this way I lose the Map interface, so I can't do things like `basket.items.keys.map(print)`. I can fix that too by adding an `UnmodifiableMapView get items` to Basket, but now the API to obtain an item is scattered over two different objects!
If anonymous classes were supported, I'd go with an anonymous implementation of Map that overrides `operator []`:
class Basket {
final Map<String, Item> items = new Map<String, Item>() {
Item operator [](String name) =>
putIfAbsent(name, () => new Item(Basket.this, name)); // `Basket.this` in Java captures the object scope of the surrounding class, if you don't know (I didn't 10 minutes ago)
};
...
}
Since I've seen that anonymous classes are not supported and not planned, and I couldn't come up with a clever google search query about my issue, I thought I'd ask here. Does Dart have an established way to handle this use case, and if not, what are your preferences and experiences? Do you prefer
* `getItem`, `setItem` and `UnmodifiableMapView` in Basket,
* a regular (non-anonymous) class that implements the desired behaviour, and is only used for this one property,
* or something I haven't thought of?
Thank you so much!
Best regards,
Philipp