Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 是否可以在Flutter中为不同的小部件使用具有抽象层的多态性?_Design Patterns_Dart_Flutter - Fatal编程技术网

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

Design patterns 是否可以在Flutter中为不同的小部件使用具有抽象层的多态性?,design-patterns,dart,flutter,Design Patterns,Dart,Flutter,我有一组大约8个小部件,它们都接受一个X类型的参数,并以不同的方式显示X类型的内容。我试图创建的是一个抽象层,它定义了这样一个小部件的结构。除了结构之外,抽象层还将定义一个工厂方法,根据ID决定使用哪个实现。不同的实现都是扩展无状态或有状态小部件的小部件 抽象层如下所示: abstract class AbstractWidget { final X content; factory AbstractWidget({@required int id, @required X content})

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

抽象层如下所示:

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);
实现如下所示:

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);
因此,我试图实现以下目标:

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);
var widgetList=new List();
for(项目中的var项目){
X content=fetchContentFromAPI();
add(AbstractWidget(内容:content,id:item.id));
}
返回列(子项:widgetList);

这将不起作用,因为AbstractWidget在技术上不是一种Widget类型,即使它只能返回无状态或有状态Widget的实例。如果有人知道一个更好的方法来实现我的结构,它将帮助我很多

使您的
抽象小部件
扩展或实现
小部件
。不过,我必须同意。抽象类不应该知道它的子类的任何信息(这就是为什么它是抽象的)。相反,我会:

class Foo扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
var widgetList=新列表();
for(项目中的var项目){
X content=fetchContentFromAPI();
add(abstractWidgetWith(content:content,id:item.id));
}
返回列(子项:widgetList);
}
Widget abstractWidgetWith({@required int id,@required X content}){
开关(id){
案例1:
返回执行1(内容);
违约:
返回执行2(内容);
}
}
}
抽象类AbstractWidget{
最终X含量;
AbstractWidget(this.content);
}
类实现1扩展无状态Widget实现AbstractWidget{
最终X含量;
实施1(本内容);
@凌驾
小部件构建(构建上下文){
//以某种方式显示内容
}
}
类实现2扩展无状态Widget实现AbstractWidget{
最终X含量;
实施2(本内容);
@凌驾
小部件构建(构建上下文){
//以某种方式显示内容
}
}
我只想补充一下你说的话:

只是,广泛的开关案例违背了我所学到的设计模式和原则

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

再次注意重复强调。当您有很多条件结构时,您往往需要一个抽象,但最后我将使用一个条件。换句话说,你不能摆脱条件结构,你只需要少用它


在这个问题的背景下,你似乎遵守了所有的规则。对我来说,这似乎是一个干净的代码。

你能不能只做一个函数来处理开关箱,而不是使用工厂构造函数?这是我最初使用的,但我想使用一个抽象,以便将来新的实现必须遵循相同的协议才能添加到列表中。但该函数可以用作您的抽象。如果您总是使用该函数而不是
AbstractWidget
构造函数,则行为大致相同。在任何情况下,对小部件使用高级继承通常都不是一个好主意。函数或组合——仅此而已。在工厂内制作开关盒与在函数内制作开关盒之间没有区别,只是改变或不改变基类。由于小部件的基类槽已经被占用,所以函数是唯一真正的替代品。这不行。Dart类不能扩展多个类。由于工厂构造函数的原因,
AbstractWidget
也不能表示为mixin。您不必扩展多个类。实现将按原样继续:
类实现1扩展无状态widget实现AbstractWidget
。但它不是一个抽象类,而是一个接口。您不能在
AbstractWidget
中定义所有子类都将使用的方法。如果您实现
AbstractClass
,它将被视为一个接口。如果您扩展了
抽象类
,它将被视为一个抽象类。当您创建
AbstractClass
扩展或实现
小部件时,这一点不会改变。由于OP正在实现
AbstractClass
,所有的子类都将使用它的方法。