はじめに
以下のようなコードを書いたとき
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'),
);
}
}
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で改行していくので肥大化していきます。
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'),
);
}
}
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定義しているので、外部からは変更不可能です。
これらを回避するために、煩雑な書き方を選択するメリットよりもデメリットのほうが大きいんじゃないかと思っています
。
本当にこれは個人的な考えなので、「そんな考え方もあるな〜」程度で捉えて貰えればなと思います。