0

我以前有以下代码,它工作正常。(请注意,Card、SearchResults、Quiz 都扩展了 Persistable,而 Persistable 包含构造函数.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);
  }
}

这有点罗嗦,所以我想我会把它分成两部分。我首先有这个:

static final Map<String, Persistable> lookup =
    {'card': Card,
     'searchresults': SearchResults,
     'quiz': Quiz };

看起来很合理,但是当我尝试重新定义该方法时,我感到困惑。

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真正的意思是 class 的一个实例Persistable。如何键入我的lookup地图,使其值属于 class Persistable,以便我可以调用它们的.fromMap构造函数?

4

1 回答 1

2

首先,我认为您的初始方法是完全有效的,不应该仅仅因为它的冗长而被抛弃。我相信替代方法会引入额外的复杂性,并且仅在您确实需要动态调度时才合理。(例如,如果您为持久性编写库,并且希望为库的客户端添加为持久性注册任意类的能力)如果您必须使用动态调度,我相信有两种主要可能性:- 反射 API。最近反射库获得了同步 API,所以这种方式现在比以前便宜得多。我相信无论如何,反思总会产生一些成本。- 使用核心 DART 功能。

使用第二种方法,您可以使用某种技巧来动态模拟构造函数调用。例如,您可以在 map 中存储的不是类型变量,而是返回所需类实例的函数:

所以你的代码可能看起来像

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);
}

在客户端:

....
registerClass('quiz', (map)=> new Quiz.fromMap(map));
registerClass('card', (map)=> new Card.fromMap(map));

(注意 - 我没有对此进行测试)您可以在https://github.com/vadimtsushko/objectory中寻找该方法的工作示例代码

于 2013-04-24T08:39:56.330 回答