I previously had the following code, it works fine. (note that Card, SearchResults, Quiz all extend Persistable, and Persistable contains the constructor .fromMap
.
Persistable fromString(String value){
Map<String, dynamic> m = parse(value);
switch(m['type']){
case 'card':
return new Card.fromMap(m);
case 'searchresults':
return new SearchResults.fromMap(m);
case 'quiz':
return new Quiz.fromMap(m);
}
}
It was a bit wordy, so I thought I would break it down into two parts. I first have this:
static final Map<String, Persistable> lookup =
{'card': Card,
'searchresults': SearchResults,
'quiz': Quiz };
Seems reasonable, but then when I try to redefine the method, I get confused.
Persistable fromString(String value){
Map<String, dynamic> m = parse(value);
String type = m['type'];
Persistable p = lookup[type];
... Confused, this can't be right
... ultimately want to "return new p.fromMap(m)";
}
Persistable p
really means a instance of class Persistable
. How do I type my lookup
map so that its values are of the class Persistable
, so that I can call their .fromMap
constructors?
First of all I think your initial approach is perfectly valid and should not be cast away owing simply to its verbosity. I believe alternative approaches introduce additional complexity and are justified only if you are really in need of dynamic dispatch. (For example if you write library for persistency and you wish to add ability to register arbitrary class for persistency for clients of library) If dynamic dispatch is a must for you I believe there is two main possibility: - Reflection API. Recently reflection library got sync API, so this way is now much more affordable then before. I believe there always will be some cost incurred by reflection anyway. - Use core DART functionality.
With the second approach you may use some sort of trick to imitate constructor call dynamically. For instance you may store in map not Type variable but function which returns instance of required class:
So your code may look something like
static final Map<String, Function> lookup = new Map<String, Function>
static void registerClass(String className, factory) {
lookup[className] = factory;
}
static Persistable getInstance(String className, Map map){
return lookup[className](map);
}
And on client side:
....
registerClass('quiz', (map)=> new Quiz.fromMap(map));
registerClass('card', (map)=> new Card.fromMap(map));
(Attention - I did not test this) You may look for working sample code for that approach in https://github.com/vadimtsushko/objectory
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.