乱数作成のロジックをAWS Lambdaに移行する
現在のアプリは状態管理にChangeNotifierProviderを使用していますが、これをRiverpodに移行しているところです。
将来、人数やコート数の設定など変数がどんどん増えていくことを想定して、今の内からコードや状態管理をシンプルにしていっています。
乱数作成ロジックの移行前の話
現在の乱数作成は全てFlutter(Dart)のコードに任せています。
しかし、計算処理に特化したようなパッケージは無いため、例えば組み合わせの「nCr」や順列の「nPr」、階乗の「n!」のような数学的な関数は無いので自分で用意する必要があります。そのほかのアルゴリズムに関するような処理もありません。
1/// lib/utils/helpers/calculation_helper_mixin.dart
2
3/// ドメインに依存しない数学的計算処理
4mixin CalculationHelper {
5
6 /// nCr: n個の中からr個を選ぶ組み合わせの数
7 int getCombinationCnt(int n, int r) {
8 final permutation = _permutation(n, r);
9 final factorial = _factorial(r);
10 final result = (permutation / factorial).floor();
11 return result;
12 }
13
14 /// n!: 階乗
15 int _factorial(int n) {
16 var result = 1;
17 for (var i = 0; i < n; i++) {
18 result = result * (n - i);
19 }
20 return result;
21 }
22
23 /// nPr: n個の中からr個を選ぶ順列の数
24 int _permutation(int n, int r) {
25 var result = 1;
26 for (var i = 0; i < r; i++) {
27 result = result * (n - i);
28 }
29 return result;
30 }
31
32 /// nCr: n個の中からr個を選ぶ全ての組み合わせ
33 List<List<int>> allCombinationList(int n, int r) {
34 if (r == 0) {
35 return [[]];
36 }
37
38 if (r > n) {
39 return [];
40 }
41
42 // 1. Include the n-th element
43 final includeN = allCombinationList(n - 1, r - 1).map((comb) {
44 return [n, ...comb]
45 ..sort((a, b) => a.compareTo(b)); // sort the inner list
46 }).toList();
47
48 // 2. Exclude the n-th element
49 final excludeN = allCombinationList(n - 1, r);
50
51 // Combine the results of including and excluding the n-th element
52 // Sort the outer list based on the entire inner lists
53 final combined = [...includeN, ...excludeN]..sort((a, b) {
54 for (var i = 0; i < a.length; i++) {
55 if (a[i] != b[i]) {
56 return a[i].compareTo(b[i]);
57 }
58 }
59 return 0;
60 });
61
62 return combined;
63 }
64}
65
それでもDartで実装するメリットもありました。
ネットワーク圏外でも使用できる
正直この部分が一番大きいかもしれません。
現在の実装ではネットワーク通信を必要としていないので、圏外の場所でも乱数表を作成することが可能です。(ブラウザで表示するような乱数表はそうもいかないかもしれないですね。)
なぜAWS Lambdaに移行したいか
乱数のロジックをAWS Lambdaに移すか🤔
— まさ𝕏個人開発 (@masa_x_dev) October 5, 2023
API叩いてデータ返す形にしよう
移行したい理由はいくつかあります。
Pythonが使える
先ほども述べたようにDartには高度や複雑な計算ができるライブラリはほとんどありません。
Pythonは数学的なライブラリも豊富にあるため、コーディングがしやすく、可読性も上がると思っているからです。
他のプラットフォームに流用できる
現在のフロントエンドはFlutterのみですが、近いうちにブラウザ版でもリリースしたいと考えています。(Next.jsを採用予定です。)
JavaScriptやTypeScriptで同じロジックを作るのは冗長ですし、ロジックに修正や改修があった場合の保守性も悪いので、ロジックを作成する部分は共通化してしまおうという狙いです。
移行する前に考えておきたいこと
完全移行してしまうと、圏外の時に乱数の作成ができなくなってしまいます。
なので、やはりローカルにも処理部分は残す必要があるなと考えているのが現状です。
ただ、今は言語間のコード変換をしてくれるAIもあるので、一旦Pythonでシンプルに実装ができたら、それをDartに変換することで、変更もしやすいのかなと思っています。
ただの雑感を文字にしただけなので取り留めがなくてすみません。。。(笑)
最後まで読んでいただきありがとうございました。