DartのenumはJavaのenumと比べて、非力かと思っています。
- Dart
値を羅列するだけ。
enum JobType {
proper,
parttime,
}
enumの一つの値に対して、データを持つことができる。
enum JobType {
PROPER(100),
PARTTIME(200),
private final int salary;
private ResultCode(int salary) {
this.salary = salary;
}
int getSalary() {
return salary;
}
}
Dartでenumの値に、名前やメソッドを付随させようとすると、swich文で実現させます。
そこで、DartでもJavaのように、値や関数を定義できるようにしたenumっぽいことをしようと思います。
想定
ユーザ登録時にDropdownMenuで「正社員」「パート」のJobTypeを選択させる。JobTypeで給与の計算方法を変更する。
JobTypeの定義
typedef GetSalary = int Function(int rage, int totalTime, int workTime);
class JobType {
JobType._(this.name, this._getSalary);
final String name;
final GetSalary _getSalary;
int getSalary(int salary, int total, int workTime) {
return _getSalary(salary, total, workTime);
}
static final proper =
JobType._('正社員', (salary, total, workTime) => salary * workTime ~/ total);
static final parttime =
JobType._('パート', (rage, total, workTime) => workTime * rage);
static final List values = List.unmodifiable([
proper,
parttime,
]);
}
- プライベートコンストラクタにすることで、外部でインスタンスを生成できなくする
- enumの値にあたるものをstatic final で定義することで、JobType.properという形でアクセスでるようにする
- 引数の型をJobTypeにした場合、JobType.properとJobType.pattimeしか選択できなくする(enum的)
- 給与を求めるファンクションの型を決めている。基本給与、総合時間、業務時間を渡すと、給与が計算される。
- 正社員には、基本給与*(業務時間/総合時間)の給与が支払われる
- パートには、時給*業務時間 の給与が支払われる
- DropdownMenuには、正社員、パートとして選択肢が表示される
- 一覧を取得できるようにvaluesのListを作る。他から変更できないように、List.unmodifiableを付ける
ユーザの定義
給与とJobTypeを設定する。あと、給与計算の方法を定義しているが、その中にJobTypeの給与計算を呼ぶようにしてある。そのため、JobTypeで定義した計算ができる。
class User {
User(this.salary, this.jobType);
final JobType jobType;
final int salary;
int getSalary(int total, int workTime) {
return jobType.getSalary(salary, total, workTime);
}
}
実際の使用
ちゃんとenumみたいに定義が一つのインスタンスであるか、のテスト。JobTypeを変更して、別々の計算方法でちゃんと正しく計算されているか、確認してます。
main() {
test('基本', () async {
expect(JobType.proper == JobType.proper, isTrue);
expect(JobType.proper == JobType.parttime, isFalse);
expect(JobType.parttime == JobType.parttime, isTrue);
expect(JobType.proper.name, '正社員');
expect(JobType.proper.getSalary(500000, 100, 100), 500000);
expect(JobType.parttime.getSalary(1000, 100, 10), 10000);
User user = User(100000, JobType.proper);
expect(user.getSalary(1000, 500), 50000);
User part = User(1000, JobType.parttime);
expect(part.getSalary(1000, 30), 30000);
});
}
まとめ
ということで、JavaのEnumをDartで実現してみました。Javaも昔はこんな方法を使っていたと思います。そのうち、Dartでも言語ベースで実装されるとよいのですが。
DropdownMenuの選択肢として使用するのが、とりあえず一番相性がいいかと思っています。参考になりどこかで使って頂けると嬉しいです!