design-patterns - 是否可以对 Flutter 中的不同小部件使用具有抽象层的多态性?

标签 design-patterns dart flutter

我有一组大约 8 个小部件,它们都接受 X 类型的单个参数,并以不同的方式显示 X 类型的内容。我试图创建的是一个定义此类小部件结构的抽象层。除了结构之外,抽象层还将定义一个工厂方法来根据 ID 决定使用哪个实现。不同的实现都是扩展 Stateless 或 StatefulWidget 的小部件。

抽象层如下所示:

abstract class AbstractWidget {
final X content;

factory AbstractWidget({@required int id, @required X content}) {
  switch (id) {
    case 1:
      return Implementation1(content);
      break;
    default: return Implementation2(content);
   }
  }
 }

实现如下所示:

class Implementation1 extends StatelessWidget implements AbstractWidget {
  final X content;

  Implementation1(this.content);

  @override
  Widget build(BuildContext context) {
    // Display content in some type of way
  }
}

所以我想要实现的目标如下:

var widgetList = new List<Widget>();
for (var item in items) {
  X content = fetchContentFromAPI();
  widgetList.add(AbstractWidget(content: content, id: item.id));
}
return Column(children: widgetList);

这不起作用,因为 AbstractWidget 在技术上不是 Widget 类型,即使它只能返回 Stateless 或 StatefulWidget 的实例。如果有人知道实现我的结构的更好方法,那将对我有很大帮助!

最佳答案

使您的AbstractWidget扩展或实现Widget。但是,我必须同意Rémi Rousselet 。抽象类不应该了解其子类的任何信息(这就是它是抽象的原因)。相反,我会这样做:

class Foo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var widgetList = new List<Widget>();
    for (var item in items) {
      X content = fetchContentFromAPI();
      widgetList.add(abstractWidgetWith(content: content, id: item.id));
    }
    return Column(children: widgetList);
  }

  Widget abstractWidgetWith({@required int id, @required X content}) {
    switch (id) {
      case 1:
        return Implementation1(content);
      default:
        return Implementation2(content);
    }
  }
}

abstract class AbstractWidget {
  final X content;
  AbstractWidget(this.content);
}

class Implementation1 extends StatelessWidget implements AbstractWidget {
  final X content;

  Implementation1(this.content);

  @override
  Widget build(BuildContext context) {
    // Display content in some type of way
  }
}

class Implementation2 extends StatelessWidget implements AbstractWidget {
  final X content;

  Implementation2(this.content);

  @override
  Widget build(BuildContext context) {
    // Display content in some type of way
  }
}

我只是想对你所说的内容进行补充:

It's just that the extensive switch case goes against the design patterns and principles I've been taught.

这里的想法是始终寻找抽象而不是重复条件结构。注意重复强调。如果多次使用条件结构,则抽象通常是更好的选择。如果情况并非如此,那么您可能通过创建抽象来解决问题。

再次注意重复强调。当你有很多条件结构时,你往往需要一个抽象,但我最终会使用一个条件。换句话说,你无法摆脱条件结构,你只是会减少使用它。

就这个问题而言,您似乎遵守了所有规则。对我来说,这看起来是一个干净的代码。

关于design-patterns - 是否可以对 Flutter 中的不同小部件使用具有抽象层的多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56168555/

相关文章:

c - 处理大量变量

c# - 链式 if 语句的模式

java - API 设计中的响应/回复模式与方法重载

flutter - 在 Flutter 中过滤和排序来自 Hive box 的记录

angular - Dartlang:pubspec.yaml中的Dev Transformers

dart - 如何在flutter的pubspec.yaml中添加swagger依赖

java - 模式 "Visitor"还是动态转换?

ios - 在 Xcode 中构建应用程序时出现 Flutter 错误 GoogleAppMeasurement

Flutter:如何在一定长度内隐藏或显示更多文本

flutter - 是否有一个订阅流,不会引发异常。相反,它会自动取消旧的订阅吗?