1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Widgetクラスのプロパティはprivateじゃなくてもいいんじゃないかという考え

1
Posted at

はじめに

以下のようなコードを書いたとき

main.dart
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
my_home_page.dart
class MyHomePage extends StatelessWidget {
  const MyHomePage({required this.title});

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
          ],
        ),
      ),
    );
  }
}

MyHomePage内の titleは外部からアクセスできてしまいます。

    final myHomePage = const MyHomePage(title: 'hoge');
    debugPrint(myHomePage.title);

これはできるだけ外側に公開しないようにprivateにしたいです。

privateなプロパティとして定義

Initializer listを使ってコンストラクタ引数を初期化するようにした場合、外部から _titleへはアクセスできないです。
しかし、コンストラクタの書き方が先程と比べて煩雑になってしまいます。コンストラクタ引数が増えたときもcommaで改行していくので肥大化していきます。

main.dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final myHomePage = const MyHomePage(title: 'hoge');
    debugPrint(myHomePage._title); // 参照できない

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
my_home_page.dart
class MyHomePage extends StatelessWidget {
  const MyHomePage({required String title}) : _title = title;

  final String _title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
          ],
        ),
      ),
    );
  }
}

まとめ - プロパティをprivateにしたときのメリット・デメリット

Widgetをファイルで分けて定義すれば先程のような感じでプロパティをprivateにして外部に公開しないようにできますが、同一のファイル内で同じことを書いた場合、実はアクセスできてしまいます。

画面ごとなど大きな単位ではファイル分けして書いていくと思いますが、複雑なデザインをまとまりのあるセクションごとに作る場合などは、1つのファイル内にまとめてある一定のUIの塊のセクションごとにprivateなクラスとして切り出してそれらを組み合わせて1つのUIを作ることもあると思います。

その場合は、同一のファイル内にいるクラスとその中のプロパティなため、Initializer listを使った書き方をしてもファイル内の他のクラスからもアクセスできてしまいます。

これはあくまで個人的な考えですが、Widgetのクラスを定義するときのプロパティは無理にprivateにする必要はないんじゃないかなと考えています。

外からプロパティが見えたとしてもWidgetをインスタンス化させてプロパティにアクセスしようとすることはほとんどないと思います。
また仮にそうするケースがあったとしても、プロパティは final定義しているので、外部からは変更不可能です。

これらを回避するために、煩雑な書き方を選択するメリットよりもデメリットのほうが大きいんじゃないかと思っています

本当にこれは個人的な考えなので、「そんな考え方もあるな〜」程度で捉えて貰えればなと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?