たとえば、「グレード」に応じてさまざまなサウンドを再生する必要があるとします。
ファイルリスト:
fairSound.mp3
goodSound.mp3
excellentSound.mp3
コード:
showResult(grade){
if(grade==0 || grade==1){
SoundUtility.play(fairSound);
}else if(grade==2 || grade==3){
SoundUtility.play(goodSound);
}else if(grade==4){
SoundUtility.play(excellentSound);
}
}
しかし、この場合は分岐をしたくないので、私の質問は、サウンドを複製することは良いパターンか反パターンかということです。
ファイルリスト:
sound0.mp3 (copy from fairSound.mp3)
sound1.mp3 (copy from fairSound.mp3)
sound2.mp3 (copy from goodSound.mp3)
sound4.mp3 (copy from goodSound.mp3)
sound4.mp3 (excellentSound.mp3)
この場合、プログラムで分岐ケースを記述する必要はありません。
showResult(grade){
SoundUtility.play(sound[grade]);
}
? DRY原則に違反していますか?
注:次のようなこともしたくありません。
var arr=[fairSound.mp3,fairSound.mp3,goodSound.mp3,goodSound.mp3,excellentSound.mp3];
グレード0を変更してfairSound.mp3を再生する場合でも、コードを変更する必要があるため、
ここで、コードを変更せずに各シングルグレードのサウンドファイルを変更することがthe要件である場合、構成を外部化(マッピング)します。
各グレードのサウンドファイル名を含むエントリを構成メカニズム(構成ファイルまたはデータベース)に作成します。
サウンドファイルを複製する代わりに、同じファイル名を複数回リストするほうがよいでしょう。
.iniファイルの例:
[resultSounds]
0=fairSound.mp3
1=fairSound.mp3
2=goodSound.mp3
3=goodSound.mp3
4=excellentSound.mp3
構成ファイルをいくつかのデータ構造(配列やハッシュマップなど)に読み込み、それをメソッドで使用して、再生するファイルを見つけます。
それは良いことでも悪いことでもありませんし、「パターン」でも「アンチパターン」でもありません。これは、(非機能的な)要件がすべてです。
コードを変更せずに、できるようにしたい"グレード0を変更してfairSound.mp3を再生する"(または別のサウンド)。これは、いくつかの学年が同じ音を持っていることが多分「偶然」であるかのように私に見えます。したがって、これらのサウンドファイルがすべて異なるかのように扱うことができます。その場合、mp3ファイルを複製する必要があることは明らかです。これにより、あるグレードのサウンドを変更しても、他のグレードは影響を受けません。
ただし、1つのサウンドのmp3ファイルを後で交換できるようにして、この特定のファイルのすべての使用法も後で(ファイルが使用されたすべてのグレードで)更新されるようにする場合は、重複を避ける必要があります。これは、質問で述べた種類の配列によって最も簡単に実現できます。後でコードを変更する必要がないようにするには、配列をコードの外部の外部構成ファイルに配置します。
TLDR;達成したい「変更可能性」の種類について考えます。「グレードごとの」変更可能性のために最適化するか、「サウンドカテゴリ」ごとの変更可能性のために最適化します。
プログラムで{
文字を2回使用すると、DRY違反になりますか?私はあなたが言うことを望みます、当然ではありません。
何かがDRYの違反であるかどうかを評価するときは、コード(またはケース内のファイル)間の類似性だけでなく、それが非常に似ている理由も考慮する必要があります。
同じである必要があるために外観が似ている場合(同じ機能が2回コーディングされているか、グレード0と1は常に同じサウンドを再生する必要がある)、DRYの違反を発見しました。
今日は同じように見えますが、まったく問題がなく、新しい要件が発生してそれが異なるものになることが予想される場合、類似性は偶発的なものであり、DRYの違反ではありません。たとえば、グレードレベル0と1で異なるサウンドを再生する要求がある可能性がある場合、sound0.mp3ファイルとsound1.mp3ファイルが現在同じであるという事実は問題ではありません。
他の答えは優れており、コードが存在しない可能性のあるファイルに依存するようになった場合の堅牢性の損失については、@ Neilに特に同意します。これらの問題(たとえば、必要なファイルが見つからない場合、起動時に詳細にクラッシュする)に対処するための構成テスト設定があると仮定すると、ファイル名でファイルを管理することは悪い考えではないと主張したいすべて。
これは、異なる環境で異なるファイルが必要な場合に特に優れたアプローチです。したがって、環境ごとにこれらのファイルの構成が異なり、スペースを節約して構成を簡素化するために、実際にファイルをコピーする必要はなく、シンボリックリンクに依存することができます。たとえば、Apacheでサイト構成に使用されているものから着想を得て、次のファイル構造を作成できます。
├── sounds-available
│ ├── excellentSound.mp3
│ ├── fairSound.mp3
│ └── goodSound.mp3
└── sounds-enabled
├── excellentSound.mp3 -> ../sounds-available/excellentSound.mp3
├── fairSound.mp3 -> ../sounds-available/fairSound.mp3
└── goodSound.mp3 -> ../sounds-available/fairSound.mp3
要約すると、このパターンは構成の柔軟性をプログラムから環境自体に移し、それはChef/Puppet/Ansibleなどの構成管理システムによって自動化およびソース制御できます。このアプローチには長所と短所がありますが、一部のユースケースでは非常に有効な選択肢であると私は主張します。
あなたがしていることは、サウンドファイルをプログラム内の識別子(文字通り、配列内のインデックス)にマッピングすることです。個々のファイルが別のファイルと無関係である場合、これはアンチパターンではありません。
ただし、今度は等級の品質を方程式に導入しているため、互いに関連するサウンドのグループになります。これを修正するには、マッピングをマッピングするにする必要があります。マッピングは任意であり、構造化の方法は完全にユーザー次第なので、これはほとんど意味がありません。したがって、これを考慮に入れるような方法で再配置することは意味があります。
考えられる1つの方法は、サウンドのサブグループを作成することです。サウンドの配列[A、B、C、D]ではなく、A、B、Cを同じサウンドの異なる品質にする場合は、[[A、B、C]、[D]]としてグループ化できます。渡されるグレードは、サブアレイのインデックスに直接対応しています。 Dが独立していることに注意してください。高いグレードのサウンドDが要求された場合、インデックスmin(gradeArr.length - 1, gradeParam)
でアイテムを取得できます。つまり、適切なグレードの品質を取得できますorそれ以外の場合に利用可能な最大値。
2番目のアプローチは、同じサウンドグレードに属するファイルを論理的にグループ化することです。したがって、サウンド「birdChirping」の場合、複数のサウンドグレードの品質を表すために、ファイルbirdChirping_01.mp3、birdChirping_02.mp3、およびbirdChirping_03.mp3が同じフォルダに存在する場合があります。プログラムでは、その名前として「birdChirping」のみを使用しています。名前とサウンドグレードを指定すると、適切なファイルを取得して再生できます。プログラムでは、すべてのサウンドをマッピングするのではなく、サウンドtype(またはこの場合は「birdChirping」)のみをマッピングします。
これは、新しいファイルごとにプログラムを切り替える必要がないという点でより動的ですが、発信者が存在しないサウンドグレードを要求すると、問題が発生する可能性があります。この方法でどのような音質を利用できるかを知るために、birdChirping _ *。mp3という名前のすべてのファイルをリストする必要がある場合があります。したがって、動的ではありますが、堅牢性も低いため、それを考慮する必要があります。
データを活用してください。必要に応じて、より役立つ構成で再配置することを恐れないでください。あなたが他の学年のセクションがあれば、プログラムは醜いはずがないと考えるのは正しいです。これはあなたがそれを修正する方法です。それ以上のチェックやマッピングをせずに、与えられたデータを元にプログラムを機能させます。
お役に立てば幸いです。