ウィジェットを拡張することは本当にアンチパターンですか?

Aug 20 2020

Flutterウィジェットを拡張することはアンチパターンであるといくつかの場所で読んだことがあります。本当?

ウィジェットのサブクラス化を使用して、削除するウィジェットをサブクラス化し、そのウィジェットをコンストラクターに配置することで、ネストを削減しました。

class Foo extends FormBuilder {
    Foo() : super (
        // bunch of widgets here
    );
}

ステートレスウィジェットを拡張する方が一般的ですが、ツリーに数行のコードとウィジェットが追加されます。これは私の好みではありません。

class Foo extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return FormBuilder(
       // bunch of widgets here
    );
}

関数からウィジェットを返すことは、レンダリングの最適化に失敗するため、アンチパターンであると読みました。私の最初のアプローチにも同様に隠れた副作用がありますか?つまり、それは本当にアンチパターンですか?

回答

3 kuhnroyal Aug 20 2020 at 20:22

ステートフルウィジェットを拡張すると、状態がスーパークラスに入力されるため問題が発生する可能性があり、ほとんどの状態クラスはプライベートに保たれるため、状態を拡張することはできません。のようなルックアップメソッドの多くはBuildContext.findAncestorStateOfType()失敗する可能性があります。

ステートレスウィジェットの拡張はほとんどの場合機能するはずですが、すでに発見しているため、お勧めしません。

一般に、Flutterのリアクティブでウィジェットの性質全体では、継承よりも構成の原則に従うのが適切なパターンです。

ウィジェットを新しいウィジェットに、新しいウィジェットに、新しいウィジェットに、新しいウィジェットに構成します...要点を理解します。

それに加えて、ほとんどが自動生成される2行のコードを保存しますが、「ウィジェットをパディングでラップ」のようなVSCode / IntelliJのすべての単純なヘルパーを自分で奪います。FormBuilderアプリ内のすべての使用法で、拡張機能をパディングでラップするのは非常に困難です。作成するのは簡単ですが、中に包むだけFooです。テーマ、色、フォントスタイルなどに使用する他のすべてのウィジェットについても同じことが言えます。パディングは単なる例です。

2 jitsm555 Aug 20 2020 at 21:16

フラッターはとcompositionいうよりはむしろですInheritance。ただし、StatelessWidgetを使用した継承は、親ウィジェットを子で再利用する必要がある場合に常に役立ちます。

例えば:

class FormBuilder extends StatelessWidget {
  Widget getWidget() {
    return Text('Child Text');
  }

  @override
  Widget build(BuildContext context) {
    return Text('FormBuilder Text');
  }
}

class Foo extends FormBuilder {
  Foo() : super();

  @override
  Widget build(BuildContext context) {
    return getWidget();
  }
}

したがって、ウィジェット要素ツリーがFoo()ウィジェットを呼び出すウィジェットは

--Foo

-コンテナ

その通常の構成の場合、要素ツリーはこれになります

class Foo extends StatelessWidget {
      Foo() : super();
    
      @override
      Widget build(BuildContext context) {
        return FormBuilder();
      }
    }

--Foo

--FormBuilder

-テキスト

その悪いパターンを述べている公式のドキュメントはありませんがComposition、念頭に置いて設計されたフラッターはありません。したがって、個人的には、このようなパフォーマンスや継承の遅れの問題Inheritanceは見たことがないので、それを使用するのは悪い選択ではないことをお勧めします。