Jan 01, 1970
これらの臭いのほとんどは、何かが間違っている可能性があることを示しているだけです。それらはそれ自体を修正する必要はありません…(ただし、調べておく必要があります。)
運用環境をチェックする IF を追加しないでください。
TL;DR: 本番環境に関連する条件を追加しないでください
def send_welcome_email(email_address, environment): if ENVIRONMENT_NAME == "production": print(f"Sending welcome email to {email_address} from Bob Builder <[email protected]>") else: print("Emails are sent only on production") send_welcome_email("[email protected]", "development") # Emails are sent only on production send_welcome_email("[email protected]", "production") # Sending welcome email to [email protected] from Bob Builder <[email protected]>
class ProductionEnvironment: FROM_EMAIL = "Bob Builder <[email protected]>" class DevelopmentEnvironment: FROM_EMAIL = "Bob Builder Development <[email protected]>" # We can unit test environments # and even implement different sending mechanisms def send_welcome_email(email_address, environment): print(f"Sending welcome email to {email_address} from {environment.FROM_EMAIL}") # We can delegate into a fake sender (and possible logger) # and unit test it send_welcome_email("[email protected]", DevelopmentEnvironment()) # Sending welcome email to [email protected] from Bob Builder Development <[email protected]> send_welcome_email("[email protected]", ProductionEnvironment()) # Sending welcome email to [email protected] from Bob Builder <[email protected]>
複雑さは、技術的な未熟さの表れです。 ATM であろうとパトリオット ミサイルであろうと、使いやすさは優れた設計の製品の真の兆候です。
ダニエル・T・リン
変数を再利用すると、スコープと境界をたどるのが難しくなります
TL;DR: 異なる的で同じ変数を読み書きしないでください
// print line total double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); // print amount total total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); // variable is reused
function printLineTotal() { double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); } function printAmountTotal() { double total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); }
汎用性の前にシンプルさ、再巧用の前に的使用。
ケブリン・ヘニー
2 つの浮動小数点数が同じであると主張するのは非常に難しい問題です
TL;DR: float を比較しないでください
Assert.assertEquals(0.0012f, 0.0012f); // Deprecated Assert.assertTrue(0.0012f == 0.0012f); // Not JUnit - Smell
Assert.assertEquals(0.0012f, 0.0014f, 0.0002); // true Assert.assertEquals(0.0012f, 0.0014f, 0.0001); // false // last parameter is the delta threshold Assert.assertEquals(12 / 10000, 12 / 10000); // true Assert.assertEquals(12 / 10000, 14 / 10000); // false
float のチェックを避けるために、テスト フレームワークに check con assertEquals()を追加できます。
Code Smell 71 - 小数点を装った魔法の浮動小数点数
神は理所当然数を作った。他のすべては人間の仕事です。
レオポルド・クロネッカー
コードの匂いを4つ組み合わせるとどうなる?
TL;DR: ゲッターを避け、セッターを避け、メタプログラミングを避ける。行動について考えます。
class Person { public string name { get; set; } }
class Person { private string name public Person(string personName) { name = personName; //imutable //no getters, no setters } //... more protocol, probably accessing private variable name }
厳しい締め切りの中で働きながら、片付けに時間をかけることほど難しいことはありません。
ケント・ベック
デフォルトとは、「まだわかっていないすべて」を意味します。私たちは未来を予見することはできません。
TL;DR: ケースにデフォルト句を追加しないでください。特殊に変更します。明确表示的であること。
ケースやスイッチ類も臭いですから避けられます。
switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; default: // if value does not presently match the above values // or future values // the following will be executed doSomethingSpecial(); break; }
switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; case value3: case value4: // We currently know these options exist doSomethingSpecial(); break; default: // if value does not match the above values we need to take a decision throw new Exception('Unexpected case ' + value + ' we need to consider it'); break; }
Code Smell 36 - Switch/case/elseif/else/if ステートメント
機能を追加するコストは、コーディングにかかる時間だけではありません。コストには、以后の拡張に対する障害の追加も含まれます。コツは、互いに競合しない機能を選択することです。
ジョン・カーマック