I am still exploring approaches to the Flyweight Pattern for Design Patterns in Dart. I have already more or less settled on a simple reflection approach, but am exploring code annotations for marking concrete flyweight classes, which is where Reflectable enters the story. And almost exited yesterday—until Sigurd told me that Reflectable currently requires an overridden dependency on the analyzer package.

So I add the appropriate dependency_overrides entry to my pubspec.yaml file:

By way of comparison, the same code based on the built-in dart:mirrors library was nearly 300K the other night. Sure, I am still compiling 5K of Dart into 100K of JavaScript, but that's a nearly 66% improvement.

Of course, what matters most is that the code actually work, which it does. Running the compiled JavaScript in Node results in my usual coffee shop output:

$ node build/bin/coffee_orders.dart.js
Served Cappuccino to Fred.
Served Espresso to Bob.
Served Frappe to Alice.
Served Frappe to Elsa.
Served Coffee to null.
Served Coffee to Chris.
Served Mochachino to Joy.
-----
Served 7 coffee drinks.
Served 5 kinds of coffee drinks.
For a profit of: $27.2

The verdict here is that Reflectable is a huge win all around. The minor, temporary issue of a out-of-sync dependency aside, Reflectable is simply better than dart:mirrors. The resulting generated code is smaller. It is easier to build. From my perspective, the biggest win is that it makes my code much cleaner.

To find classes annotated with the custom @flavor annotation in dart:mirrors, I had to traverse libraries and declarations. It was ugly:

The Reflectable @flavor annotation just knows the classes that it annotates. What could be easier?

That said, I am not sold on annotations as the best approach to concrete flyweight classes in Dart. I may try my original, not-annotated solution again—but with Reflectable. It could be that Reflectable is optimized for annotations, but other cases still work equally or more well in dart:mirrors. I will find out with at least one other case. Tomorrow.

3 comments:

Hi Chris,we just published version 0.3.4 of reflectable, which includes a rather long list of bug fixes and also the version constraint that Sigurd mentioned. So you should be able to do `pub upgrade` to get it (after deleting the 'dependency_overrides' directive from your 'pubspec.yaml'). That way you'll also get the newest version of the analyzer automatically when the stricter-than-normal version constraint in reflectable is removed.

One more thing came to mind when I took a brief look at https://dartpad.dartlang.org/c7dabc0c57a93e8d88d7: Did you consider putting `@flavor` only on `class CoffeeFlavor`, and then using `subtypeQuantifyCapability`?