質問
プログラムについて議論するとき、「ロジック」または「ビジネスロジック」という用語がよく使用されます。
例:
- (ユニットテストについて)テストでコードを100%カバーする必要はありません。 ロジックのみをテストするだけで十分です。
- (Webアプリケーションについて)コントローラーにビジネスロジックを含めることはできませんが、他のクラスのメソッドのみを呼び出す必要があります
- VIEWレイヤーにビジネスロジック (つまり、JSPファイル)がないようにする必要があります
それでは、誰が「ロジック」とは何かを教えてくれますか? これはコード内のIFを意味しますか? しかし、本当にIFのないコードはありますか? または(ビジネス-)「ロジック」とは、クライアントからの情報を意味しますか? しかし、クライアントが注文しなかったお金で何かをすることはできますか? できません。 したがって、すべてのコードは完全にクライアントからの「ビジネスロジック」です。 それが、私が地獄の論理が何であるかを決して理解できなかった理由です。
答え
おそらく、「論理」という言葉の代わりに「知識」という言葉を使用すれば、この質問に対する答えはより簡単になります。 ロジックは、コードに関する知識、またはコードの動作方法です。 また、次のように定式化することもできます。「ロジック」は、少なくとも1回はコメントしたいものです。
例
たとえば、最近プロジェクトで掘り起こしたAccountクラスを取り上げます。
そうだった。 私たちのオフィスでのある晴れた日、インターネットは数時間遮断されました。 私は実際に仕事をすることができませんでした-まあ、そこには、svn、jira、ナレッジベースなどがありませんでした。 そして、あるクラスのユニットテストを書く練習として決めました。 そして、アカウントに出くわしました:
public class Account { // Negative amount means that account is prepaid private BigDecimal amount; public BigDecimal getAmount() { return amount; } // }
ここでテストするように見えますか? IFはどこにありますか? ロジックはどこにありますか? 何もありませんし、テストするものもありません。 可変
amount
についてのコメントに突然気付いたとき、私はすでにこのクラスをドロップしてより複雑なものを見つけたいと思っていました:
マイナスの金額は、アカウントが前払いされていることを意味します
これは何?
「金額」はこのクライアントの総負債であり、クライアントが前払いを行った場合、マイナス記号付きの「負債」であることがわかります。 さて、これはコードに関するある種の知識です。 このコメントを単体テストに変えてみましょう:
public class AccountTest { @Test public void negativeAmountMeansThatAccountIsPrepaid() { Account prepaidAccount = new Account(-123); assertTrue(prepaidAccount.isPrepaid()); } }
負の「量」の場合をチェックしているので、正の場合をチェックするといいでしょう。
@Test public void positiveAmountMeansThatAccountIsInDebt() { Account indebtAccount = new Account(456); assertFalse(indebtAccount.isPrepaid()); assertTrue(indebtAccount.isInDebt()); }
そのため、誤って2つの新しいメソッドisPrepaidとisInDebtがありました。もちろん、その実装は明らかです。
public class Account { private BigDecimal amount; public boolean isInDebt() { return amount > 0; } public boolean isPrepaid() { return amount < 0; } }
おわかりのように、すでにコードにIFが登場しています!
同時に頭に浮かぶ次の考え:おそらくこれらのIFはすでにどこかにあったのでしょうか?
私は少し見なければなりませんでしたが、それは価値がありました。 これらのIFは実際にはコード内にあり、どこかにではなく、JSPファイル、つまり「ビュー」レイヤーにあり、定義上、ロジックはないはずであることが判明しました。
<%-- Positive amount means that account is in debt %--> <c:if test="${account.amount > 0}"> <font color="red"> !</font> </c:if> <c:if test="${account.amount < 0}"> <font color="green"></font> </c:if>
おお、なんて面白い! そこで、2番目のテストケースが浮上しました。 なんて素晴らしい。 ここで、メソッド
isInDebt
および
isPrepaid
があるため、JSPからロジックを削除できます。
<c:if test="${account.inDebt}"> <font color="red"> !</font> </c:if> <c:if test="${account.prepaid}"> <font color="green"></font> </c:if>
良くなった? なったと思います。 これは、カプセル化に少し似ています-implementation索好きな目から実装を隠します。 Amountクラスのみが、その場合にクライアントがお金を借りているかどうかを知っています。 世界中の誰もこれがどのように起こるかを知りません-クライアントは
isPrepaid
と
isPrepaid
を使用して既製のソリューションを
isPrepaid
。 理論的には、値「debt」および「preayment」は、通常、データベースの異なる列、または一般的には異なるテーブルおよび一般的に異なるデータベースに格納できます。 現在、2つのメソッドが存在するため、このロジックは
Account
クラスに隠されています(カプセル化されています)。
それでも信じられない場合は、コードの量を比較してください。
だった
| になっています
|
さらに進んで、
getAmount()
代わりに
getAmount()
と
getAmount()
2つの異なるメソッドを
getPrepaidAmount()
ます。 さらに、それらの中では、クライアントが本当に借金または前払いがあるかどうかを確認できます。 つまり、たとえば、次のようなコードを書くことは不可能になります。
<%-- , . %--> <c:if test="${account.amount != 0}> <font color="red"> !</font> </c:if>
理想的には、getAmount()メソッドを完全に消去できるようになりました。 これは本当のカプセル化です。データとコードを隠し、メソッドを通してのみアクセスを許可します。 もしインターネットが修理されていなかったら、他の20人のゲッターセッターを排除できただろうと思います。
道徳
単体テストが読みやすく、オブジェクト指向のコードをどのように導くかがわかります。 そして、あなたは言う:「私のコードにはロジックがありません、テストするものは何もありません...」そのままです!
論理があります。