Можно ли использовать полиморфизм со слоем абстракции для разных виджетов во Flutter? - PullRequest
1 голос
/ 16 мая 2019

У меня есть набор из примерно 8 виджетов, которые все принимают один параметр типа X и по-разному отображают содержимое типа X.Я пытаюсь создать слой абстракции, который определяет структуру такого виджета.Помимо структуры, уровень абстракции будет определять фабричный метод, чтобы решить, какая реализация будет использоваться на основе идентификатора.Различные реализации - это все виджеты, которые расширяют 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- или StatefulWidgets.Если кто-нибудь знает лучший способ реализации моей структуры, это мне очень поможет!

1 Ответ

0 голосов
/ 16 мая 2019

Заставьте 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
  }
}

Я просто хочу добавить кое-что к тому, что вы сказали:

Просто обширный случай переключения идет вразрез с шаблонами и принципами проектирования, которым меня учили.

Идея здесь в том, чтобы всегда искать абстракцию вместо повторяющихся структур условий. Обратите внимание, повторяет подчеркивание. Если структура условий используется более одного раза, абстракция в большинстве случаев является лучшим вариантом. Если это не так, вы, вероятно, преодолеваете проблему, создавая абстракцию.

Опять же, обратите внимание , повторяя , подчеркивая. Вам, как правило, нужна абстракция, когда у вас много структур условий, но в итоге я в итоге буду использовать условие ONE . Другими словами, вы не можете избавиться от структур условий, вы просто будете использовать их меньше.

В контексте этого вопроса кажется, что вы следовали всем правилам. Это похоже на чистый код для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...