アンチパターン:マジックナンバー
1. 序章
デザインパターンは、ソフトウェア開発のマップとして機能します。 これらのパターンは、繰り返し発生するプログラミングの課題に効率的に取り組む方法を示唆しています。 このように、パターンはいくつかの異なるプログラミングプロジェクトに適合するのに十分な汎用性があり、異種のコンテキストで同じ問題を解決します。
ただし、アンチパターンはソフトウェア開発で頻繁に行われることであり、実際にはあまり効率的ではありません。 したがって、最終的なソフトウェアを改善する代わりに、アンチパターンはソフトウェアの開発と保守を困難にします。
このチュートリアルでは、マジックナンバーと呼ばれるアンチパターンについて学習します。最初に、パターンとアンチパターンについて簡単に説明します。 そこで、マジックナンバーのアンチパターンについて説明します。 最後に、魔法の数字とそれらをコードから削除するための実践のいくつかの実用的な例を見ていきます。
2. デザインパターン
さまざまなプログラミングプロジェクトで、いくつかの課題と問題が繰り返し発生します。 そのため、ある時点で、ソフトウェアエンジニアとコンピューティング研究者はこれらの問題と課題を要約し、それらを解決または回避するためのデザインパターンを提案しました。
デザインパターンはコード自体ではありません。実際、これらのデザインはコードを整理および開発する方法を示しています。
デザインパターンを採用することの大きな利点は、それらがすでに多くの開発者によって採用され、テストされていることです。 このように、開発者がデザインパターンを使用して承認すればするほど、プログラミングプロジェクトの潜在的な問題や課題を解決するために機能することが保証されます。
プログラミングプロジェクトでデザインパターンを採用することの一般的な利点は次のとおりです。
- 生産性:デザインパターンがプログラミングの問題を回避するため、ソフトウェア開発に必要なデバッグと問題解決の段階が少なくなり、全体的な生産性が向上します。
- 保守性:ほとんどのデザインパターンは、低結合で標準化されたコーディングに依存しています。 したがって、ソフトウェアの機能の変更、削除、または追加は簡単です。
- サポート:特定のデザインパターンの実践者のオープンコミュニティがいくつか存在します。 これらのコミュニティには、情報やサポートを得るためのフォーラムやQ&Aページがいくつかあります。
さまざまな目的の複数のデザインパターンがあります。ただし、有名なデザインパターンとして、抽象ファクトリ(作成パターン)、フライウェイト(構造パターン)、およびmemento(動作パターン)。
2.1. アンチパターン
要約すると、アンチパターンは、利点を示さず、他のデザインパターンから得られる利点を損なう可能性のあるパターンです。
アンチパターンは、最初は不快ではない、または有益であると思われる悪い習慣または反復的な行動として理解できます。 ただし、プログラミングプロジェクトの進行に伴い、チームにとってアンチパターンが問題になります。
さらに、アンチパターンは解決可能です。したがって、ソースコードからアンチパターンを削除するためのリファクタリングの標準的で再現可能なプロセスがあります。
有名なアンチパターンの例としては、最先端(組織的なアンチパターン)、金メッキ(ソフトウェア設計のアンチパターン)、マジックナンバー(プログラミングのアンチパターン)があります。
次のセクションでは、マジックナンバーのアンチパターンについて詳しく調べます。
3. マジックナンバー
一般的に、マジックナンバーはソースコードの処理ルーチンで直接使用される数値です。 魔法の数の雇用には複数のシナリオがあります。 これらのシナリオの最も一般的なものは次のとおりです。
- ソースコードに1つ以上出現する名前のない定数値
- 実際にはプロトコルまたはファイル形式の識別子である不特定の値
- グローバルな意味を持たない特定のソースコードでのみ使用される一意の値
魔法の数のシナリオに関係なく、それらの発生はプログラミングプロジェクトの保守性と単純さを損なう可能性があります。
マジックナンバーの最初の潜在的な問題は、ソースコードに精通していないプログラマーがそれに取り組み始めたときに発生します。
マジックナンバーには、それらが何であるかについての明確な説明がありません。したがって、プログラマーは、コード内の各マジックナンバーの意味と出現を追跡する必要があります。
別の問題は、複数回出現するマジックナンバーを変更することです。この場合、プログラマーはコードのさまざまな場所でいくつかの変更を実行します。 このプロセスでは、変数または定数の値を変更するだけでなく、はるかに多くの労力と時間が必要になります。
最後に、マジックナンバーを使用すると、プログラミングプロセスがタイプミスの影響を受けやすくなります。 これは、魔法の数字が大きな数字であり、1つまたは2つの間違った数字だけを検出するのが難しい場合に特に関係があります。
前述の問題を回避することに加えて、マジックナンバーを使用しないでください。たとえば、次のような他の利点があります。
- IDEおよびテキストエディタによって提供されるコード補完の使用法を改善します
- すべての変数と定数がマジックナンバーを置き換えて、ソースコードにブロックを作成できるようにします
- コードの文書化を容易にします
次のサブセクションでは、マジックナンバーが使用される最も一般的なシナリオの例を示します。
3.1. 名前のない定数値
通常、ソースコードでループの停止基準を定義する名前のない定数値が見つかります。これらの定数は、通常、コード内で長期間変更されません。 たとえば、SHA1 hash をバイトごとに検査する場合、常に20バイトで作業します。
SHA1ハッシュ検査がマジックナンバー(赤い番号)で行われる例を見てみましょう。
ただし、システムでSHA2のSHA1ハッシュを変更する場合は、コード内のすべてのSHA1の長さのマジックナンバーを追跡し、それらをSHA2の長さの値(32)に変更する必要があります。
これを回避するために、ハッシュ長の定数を定義し、マジックナンバーの代わりにそれを使用できます。以下の例を参照してください。
3.2. 名前のない識別子の値
実際には、名前のない識別子も定数値です。 ただし、この特定のケースでは、プロトコル、ファイル形式、またはコード内の他の特定の識別子を表します。
これらの識別子が発生するシナリオの例は、ネットワークトラフィックのヘッダーを処理する場合です。 特定の例は、IPv4のフィールドProtocolまたはIPv6のNextHeader で、パケット内の次のヘッダーレイアウトのコードを伝送します。
IPパケットの次のヘッダーが予期されたものであるかどうかを確認するアルゴリズムを考えてみましょう。 したがって、マジックナンバーを使用してそれを実装すると、次のようになります。
IPv4パケットの特定の位置(P [9])にアクセスするために使用されるインデックスは、マジックナンバーとしても機能することに注意してください。 この種のマジックナンバーについては、次のサブセクションで説明します。
マジックナンバーを回避し、必要に応じてプロトコル検証を簡単に変更できるようにするために、次の例に示すように、プロトコル識別子の値を保持する定数を定義できます。
3.3. グローバルな意味のない一意の値
グローバルな意味を持たない一意の値は、通常、特定のアルゴリズムの特定のルーチンとして発生します。 例として、クライアントアルゴリズムがサーバーに接続するために実行する最大試行回数を見ることができます。
次に、アルゴリズムは前述の例を示します。
マジックナンバーの使用を回避するために、必要な接続試行回数を定義する変数または定数を使用できます。 下記参照:
4. 結論
このチュートリアルでは、マジックナンバーと呼ばれるアンチパターンを学習しました。 最初に、アンチパターンの概念に焦点を当てたデザインパターンの簡単なレビューを見ました。 したがって、特にマジックナンバーのアンチパターンを調査し、通常発生するさまざまなシナリオの例を示しました。
アンチパターンを使用すると、通常、プログラミングプロジェクトでいくつかの将来の課題が発生すると結論付けることができます。 具体的には、マジックナンバーは、ソースコードの保守性と理解性に問題を引き起こす可能性があります。
このようにして、これらの潜在的な問題を回避するために、整理された直感的な方法でマジックナンバーを変数と定数に置き換えることができます。