データフローの制御
学習の目的
この単元を完了すると、次のことができるようになります。
- 比較演算子の使用方法を挙げる。
- switch と if-else ステートメントの違いを説明する。
日常生活では、常に決定を下さなければなりません。何を着るか? 何を食べるか? 左と右のどちらに進むべきか? 同じことがコードの記述でも発生します。単元 1 の Teatime 擬似コード、特にステップ 2 を思い出してください。
Boil water in a Tea Kettle Fill Kettle with Water Switch Kettle On Wait for Water to Boil
特に問題はなさそうに見えますね。お湯を沸かす、ケトルに水を満たす、ケトルをオンにする、お湯が沸くまで待つ。ただし、ケトルにすでに少し水が入っている場合はどうしますか? ケトルが一杯だったらどうでしょう? お湯が沸くまでどのくらい時間がかかりますか?
式と式の演算子
決定を下す前には大抵、比較をします。これは何より大きいか? これは何と等しいか? 開発者は多くの場合、アプリケーションで値を比較してから決定を下します。コードでは、2 つの式を、その間に式の演算子を置いて比較します。
式は、評価されると結果が 1 つの値になるコードスニペットです。このモジュールの目的上、式はリテラル値 (12 など)、変数 (numberOfTeaCups など)、または数学演算 (7 x 4 など) になる可能性があります。
式の演算子は、2 つの値を比較したり、等しいことを示したりします。比較ステートメントは、2 つの式とその間にある式の演算子で構成され、結果は Boolean 値 (true または false) になります。
比較演算子
演算子 | 説明 | 構文 | 結果 |
---|---|---|---|
< |
次の値未満 |
1 < 2 |
TRUE |
<= |
次の値以下 |
1 <= 2 3 <= 3 |
TRUE |
== |
次の値と等しい |
10 == 10 |
TRUE |
!= <> |
次の値と等しくない |
10 != 0 10 <> 11 |
TRUE |
> |
次の値より大きい |
11 > 10 |
TRUE |
>= |
次の値以上 |
40 >=10 40 >= 40 |
TRUE |
次の値と等しい演算子にはなぜ 2 つの等号が使用されるのでしょうか? 1 つの等号を次のステートメントで使用したことを思い出してください。
1 つの等号 (=
) は代入演算子です。値を代入します。2 つの等号 (==
) は比較演算子です。2 つの値を比較して、それらが等しいか (true)、否か (false) を判定します。
演算子は、既知の値を変数と比較する場合や、2 つの異なる変数の値を比較する場合に特に役立ちます。
Integer numberOfTeaCups = 2; numberOfTeaCups == 3; //false numberOfTeaCups == 2; //true
ここまでに整数変数と文字列変数の例を見ました。比較の結果を保持する Boolean 変数も作成できます。次のコードを見てください。
Integer numberOfTeaCups = 2; Boolean result = numberOfTeaCups > 3; // 2 > 3 = false
行 1 では、numberOfTeaCups 変数を 2 に設定します。
行 2 では、result
という名前の Boolean 型変数を作成し、numberOfTeaCups 変数の値を数値 3 と比較し、比較の結果 (false) を result
変数に代入します。
比較はあるものと別のものの関係を判定するのに便利ですが、最も効果を発揮するのは条件付きステートメント内で決定を下す場合です。
条件付きステートメント
開発者は、条件付きステートメント内で式を使用して意思決定構造を作成し、その中で 1 つ以上の条件を指定してプログラムで評価または検査します。なにやら長い説明ですね。詳しく見ていきましょう。
条件付きステートメントでは、複数のオプションを設定します。Flow Builder で条件を作成したことがあれば、すでに条件付きステートメントを使用しています。たとえば、「[州] が「California」と等しい場合、リストビューにレコードを表示する」は条件付きステートメントです。「[州] が「California」と等しい場合」は条件で、「リストビューにレコードを表示する」は、条件が true の場合にのみプログラムで実行されるアクションです。この例では、2 つのオプションはレコードを表示する (明示的) と、レコードを表示しない (暗黙的) です。
if-else ステートメント
Apex でよく使用される条件付きステートメントは if-else
ステートメントです。次のようになります。
if(condition is true) { //do this } else { //do this }
行 1 では条件を定義します (括弧内に記述)。
行 2 には、行 1 が true の場合に実行するコードが含まれます。
行 3 では 2 つ目のオプションである else オプションが記述されます。
行 4 には、行 1 が false の場合に実行するコードが含まれます。
Apex では、条件ステートメントを波括弧 {}
内に記述します。各開き波括弧 ({
) は閉じ波括弧 (}
) と対になっている必要があります。コードのブロックに開き波括弧があって閉じ波括弧がない場合、エラーが発生します。
Teatime 擬似コードで条件付きステートメントを使用して、ティーケトル内の水の量をチェックし、その量に基づいて次に行うことを決定しましょう。
- 開発者コンソールで、[Debug (デバッグ)] | [Open Execute Anonymous Window (匿名実行ウィンドウを開く)] をクリックします。
- 次のコードをコピーして、[Enter Apex Code (Apex コードを入力)] ウィンドウに貼り付けます。
String waterLevel = 'full'; /*This variable keeps track of the water level status: full or empty*/ if(waterLevel == 'empty') { System.debug('Fill the tea kettle'); waterLevel = 'full'; /*Once the tea kettle is filled the variable is changed to full*/ } else { System.debug('The tea kettle is full'); }
- [Open Log (ログを開く)] チェックボックスをオンにして、[Execute (実行)] をクリックします。実行ログが開き、コードの実行結果が表示されます。
- ウィンドウ下部の [Debug Only (デバッグのみ)] チェックボックスをオンにします。
行 1 では、waterLevel 変数を full
に初期化します。一般に、コードの変数値はユーザーが入力するか、他のデータから求められ、コード自体には指定しません。Teatime の例では、ケトルのセンサーから物理的なデータを取得して、水の量を判定します。こうしたデータがない場合、開発者はコードを実行してテストできるように、コードに直接 (一時的に) 値を設定します。コードに値を設定することを、ハードコード化と言います。ここではテスト目的で、waterLevel 変数の値を full
にハードコード化しています。値はすでに設定されていて、waterLevel が empty
(空) で開始することはないため、最初の if
ステートメント (行 3) は実行されません。
コードは waterLevel 変数が empty
(空) と等しいかチェックします。waterLevel は full
(一杯) にハードコード化されているため、if
ステートメントの条件は false になります。if
条件が false の場合、else
コードブロックが実行されます。
このコードでは現在、水の量が full
(一杯) の場合と empty
(空) の場合という、2 つのオプションを処理します。ただし、可能性はそれだけではありません。ケトルの途中まで水が入っている場合もあります。2 つの可能性以外をどう処理すればよいのでしょうか?
if-else if ステートメント
3 つ以上の可能性を処理するには、if-else if ステートメントを使用します。if-else if ステートメントでは、最後の else 条件の前にもう 1 つ if 条件を追加します。実際の例を見てみましょう。
- 開発者コンソールで、[Debug (デバッグ)] | [Open Execute Anonymous Window (匿名実行ウィンドウを開く)] をクリックします。
- 次のコードをコピーして、[Enter Apex Code (Apex コードを入力)] ウィンドウに貼り付けます。
String waterLevel = 'half'; if(waterLevel == 'empty') { System.debug('Fill the tea kettle'); waterLevel = 'full'; } else if(waterLevel == 'half') { System.debug('Fill the tea kettle'); waterLevel = 'full'; } else { /*This statement only runs if line 3 and line 6 result in false.*/ System.debug('The tea kettle is full'); }
- [Open Log (ログを開く)] チェックボックスをオンにして、[Execute (実行)] をクリックします。実行ログが開き、コードの実行結果が表示されます。
- ウィンドウ下部の [Debug Only (デバッグのみ)] チェックボックスをオンにします。
コードをテストするときに、行 1 の waterLevel
変数の値を変更します。デバッグログの出力に変更が反映されます。3 つの値、half
(半分)、full
(一杯)、empty
(空) を試してみましょう。
最初の条件が最も可能性が高い条件になるように、条件ステートメントを配置します。こう配置することで、コードブロックの実行時に毎回実行されるコードの量が減ります。Teatime の例では、ケトルは空である可能性が最も高いので、その条件を最初に置きます。ティーケトルが一杯である可能性は低いため、その条件を最後にチェックします。
switch ステートメント
if-else ステートメントのより効率的な代替手段が switch ステートメントです。switch ステートメントは、値のセットを指定し、式を評価してそれらの値のどれと一致するかを判定します。次のようになります。
switch on expression { when value1 { //code block 1 } when value2 { //code block 2 } when else { //if none of the previous values apply //code block 3 } }
switch ステートメントでは、when
予約語の後に 1 つ以上の値を指定できます。
switch on expression { when value1 { //single value //code block 1 } when value2, value3 { //multiple values //code block 2 } }
Teatime 擬似コードに switch を適用してみましょう。
- 開発者コンソールで、[Debug (デバッグ)] | [Open Execute Anonymous Window (匿名実行ウィンドウを開く)] をクリックします。
- 次のコードをコピーして、[Enter Apex Code (Apex コードを入力)] ウィンドウに貼り付けます。
String waterLevel = 'empty'; //option 1 using a single value switch on waterLevel { when 'empty' { System.debug('Fill the tea kettle'); } when 'half' { System.debug('Fill the tea kettle'); } when 'full' { System.debug('The tea kettle is full'); } when else { System.debug('Error!'); } } //option 2 using multiple values switch on waterLevel { when 'empty', 'half' { //when waterLevel is either empty or half System.debug('Fill the tea kettle'); } when 'full' { System.debug('The tea kettle is full'); } when else { System.debug('Error!'); } }
- [Open Log (ログを開く)] チェックボックスをオンにして、[Execute (実行)] をクリックします。実行ログが開き、コードの実行結果が表示されます。
- ウィンドウ下部の [Debug Only (デバッグのみ)] チェックボックスをオンにします。
論理演算子
ここまで複数の条件を処理する方法を見てきました。では、1 つの条件が複数の値で満たされる場合はどうすればよいでしょうか?
論理演算子
演算子 | OR | AND |
演算子記号 | || | && |
擬似コード | X または Y の場合は、これを実行する。 それ以外の場合は、それを実行する。 |
X かつ Y の場合は、これを実行する それ以外の場合は、それを実行する |
Apex コード |
if(X || Y) { |
if(X && Y) { |
論理演算子 and
と or
を使用すると、複数の値をチェックして、条件が true か false かを判定するコードを記述できます。and
演算子では、条件を満たすにはすべての値が true になる必要があります。or
演算子では、条件を満たすには 1 つ以上の値が true になる必要があります。
論理演算子の評価
論理演算子 | 構文 | 説明 |
---|---|---|
&& (AND) |
X && Y |
X と Y は Boolean 値です。X と Y が両方とも true の場合、式は true になります。それ以外の場合、式は false になります。 |
|| (OR) |
X || Y |
X と Y は Boolean 値です。X と Y が両方とも false の場合、式は false になります。それ以外の場合、式は true になります。 |
論理演算子を試してみましょう。次のコードは if-else if ステートメントとして記述したときのものです。
String waterLevel = 'half'; if(waterLevel == 'empty') { System.debug('Fill the tea kettle'); waterLevel = 'full'; } else if(waterLevel == 'half') { System.debug('Fill the tea kettle'); waterLevel = 'full'; } else { //This statement only runs if line 3 and line 6 result in false. System.debug('The tea kettle is full'); }
行 4 ~ 5 と行 7 ~ 8 を見てください。まったく同じです。これを冗長コードと呼びます。ベストプラクティスとして冗長性をなくすことで、コードが読みやすくなり、理解、デバッグ、メンテナンスが容易になります。この例のコードでは、waterLevel が empty
でも half
でも同じアクションを実行します。empty
と half
を 1 つの条件にまとめることで、コードを簡素化できます。or
演算子を使用して、どちらかの値 (empty
または half
) が true の場合に条件が満たされるようにします。
- 開発者コンソールで、[Debug (デバッグ)] | [Open Execute Anonymous Window (匿名実行ウィンドウを開く)] をクリックします。
- 次のコードをコピーして、[Enter Apex Code (Apex コードを入力)] ウィンドウに貼り付けます。
String waterLevel = 'half'; if(waterLevel == 'empty' || waterLevel == 'half') { System.debug('Fill the tea kettle'); waterLevel = 'full'; } else { //This statement only runs if line 3 false. System.debug('The tea kettle is full'); }
- [Open Log (ログを開く)] チェックボックスをオンにして、[Execute (実行)] をクリックします。実行ログが開き、コードの実行結果が表示されます。
- ウィンドウ下部の [Debug Only (デバッグのみ)] チェックボックスをオンにします。
どうでしょう? コードの冗長性がなくなりました。論理演算子 (&&
と ||
) を使用することは、冗長コードを削除または削減し、読みやすくするための有効な方法です。
コードを整然とした状態に保つ
プログラミングでは大抵、何かを行うのに複数の方法があります。たとえば、switch ステートメントと if-else ステートメントのどちらを使用しても同じ結果になることがあります。重要なのは、使用するステートメントの種別を選択するときには、それぞれがコードの読みやすさにどう影響するかを考慮することです。コードの経験を積んでいけば、コードを整然とした状態に保つさまざまな方法がわかるようになります。現時点では、コードの読みやすさと理解しやすさを高めることに集中しましょう。