Builderパターンについて軽く
あるクラスのコンストラクタで設定する変数の数が多く、
けど、全部必須ではない場合、
必須ではない変数の設定パターンによって、コンスラクタの数が膨大になってしまう。
また、コンストラクタでは必須の変数のみ設定し、
後からセッターで他の変数を設定するという場合でも、
呼び出すセッター文が膨大になってしまい、呼び出し元でのオブジェクト生成箇所が長くなってしまう。
これを回避するために、
決まった値でのオブジェクト生成部分を手順化したクラスを別で用意し、対象オブジェクトを生成するというパターン。
この手順が記載されたクラスを Director
と呼び、
Director が作成するクラスを Builder
と呼ぶ。
このパターンを使う時、 Director
は手順のみ記載し、
Builder
のサブクラスなどに流用できるように、
必須パラメータであってもセッターで設定するようにし、固定のクラスのコンストラクタではない形にした方が良さそう。
また、 Director
は決まった値での手順になるので、
値が流動的な時は、このパターンは使いづらいのかもしれない。
サンプルとして何を作ったか
「☆3出力」ボタン
と
「♪3出力」ボタン
を押すとそれぞれ対象の文字が表示される。
表示する文字数の設定を
Director
と Builder
で定義する。
クラス図
コード
GitHub に完全版があります。
abstract class DecorationBuilder {
set characterNum(int characterNum);
String output();
}
import 'package:flutter_builder/utils/decoration_builder.dart';
class DecorationStar implements DecorationBuilder {
final _character = '☆';
int? _characterNum;
@override
set characterNum(int characterNum) {
_characterNum = characterNum;
}
@override
String output() {
String outputString = '';
for (var i = 0; i < _characterNum!; i++) {
outputString = '$outputString$_character';
}
return outputString;
}
}
import 'package:flutter_builder/utils/decoration_builder.dart';
class DecorationMusicNote implements DecorationBuilder {
final _character = '♪';
int? _characterNum;
@override
set characterNum(int characterNum) {
_characterNum = characterNum;
}
@override
String output() {
String outputString = '';
for (var i = 0; i < _characterNum!; i++) {
outputString = '$outputString$_character';
}
return outputString;
}
}
import 'package:flutter_builder/utils/decoration_builder.dart';
class Director {
DecorationBuilder? _decorationBuilder;
Director(DecorationBuilder decorationBuilder) {
_decorationBuilder = decorationBuilder;
}
void construct() {
_decorationBuilder?.characterNum = 3;
}
}
:
: // 割愛
:
class _MyHomePageState extends State<MyHomePage> {
final _textController = TextEditingController();
String _outputText = '';
DecorationBuilder? _decorationStar;
DecorationBuilder? _decorationMusicNote;
@override
void initState() {
super.initState();
_decorationStar = DecorationStar();
Director director = Director(_decorationStar!);
director.construct();
_decorationMusicNote = DecorationMusicNote();
director = Director(_decorationMusicNote!);
director.construct();
}
:
: // 割愛
:
以上