「クリーンコード」で説明されている一連のルールを考えると、for
ループを実際に使用できますか?私の混乱は、for
ループ自体が低レベルの構成体であるという事実から生じます。したがって、それは本によって、非常に低い抽象化レベルでのみ使用できます。しかし、それは、抽象化のより高いレベルに属するコードの一部、つまり関数が呼び出されているコードの一部でループの使用が禁止されていることを意味しますか?
この本のように、「低レベルと高レベルを混ぜないでください」という観点からコードを調べようとしたところ、for
ループを作成することすらできないことに気づいたので、私は尋ねています。これは私をクロールまで遅くしました(いつものカメの遅いコーディングよりも遅い)。
Clean Codeの「関数ごとに1レベルの抽象化」の原則を参照していると思います。
この一般的な原則は完全に理にかなっています。 抽象化のレベル は、複雑さを習得するために、より低いレベルの詳細を隠すことです。したがって、異なるレベルの抽象化を混在させることは、より高いレベルの複雑さを非表示/カプセル化しようとする試みが、より低いレベルを同時に使用することによって破られることを意味します。したがって、カプセル化の利点が失われます。
これは、さまざまな指示に与える価値判断とは関係ありません。 for
が低レベルであると考える場合、if
、while
、return
、関数呼び出しなどについても同様に考えることができます。
したがって、ルールに違反することなく、for
をデザインで使用できます。
備考:forループを使用して非表示にする必要がある詳細レベルにアクセスする場合、ルールに違反する可能性があります。たとえば、高レベルの関数でfor
を使用して配列を反復処理する場合、検索を実行するための高レベルの関数がすでにある場合です。
まず、本Clean Codeがルールではなくguidelinesを提案していることを覚えておく価値があります。ここで参照されている特定のガイドラインは、抽象化のレベルを混在させない推奨事項であるようです。
このアドバイスは、具体的にはクラスインターフェイスの設計に言及していることを覚えておく価値があります。 (つまり、パブリック/保護されたメソッド、パブリックプロパティ-クラスを使用する何かに公開されるものすべて)
高レベルの抽象クラスAnimal
を考えてみましょう。そこから低レベルの具象クラスDog
が派生します。 Dog
には、Dog
の抽象化レベルに適していると思われるBark()
というメソッドを含めることができます。
ただし、Bark()
メソッドがabstractAnimal
クラスのインターフェースに含まれるのを止めるものは何もありません。しかし、Animal
から派生した他のクラスがBark()
メソッドを使用できない場合、これはコードの匂いになります。 Animal
から派生したものは、Bark()
メソッドが具象クラスに完全に不適切であっても、Bark()
メソッドを継承(さらにはオーバーライド)する必要があります。
つまり.
public abstract class Animal
{
public abstract void Bark();
}
public class Elephant : Animal
{
public override void Bark()
{
// HUH?!
}
}
このアドバイスは一般的に、高水準の抽象化/インターフェースで提供するメソッドについて慎重に検討することを奨励しています。派生( "下位レベル")クラスに、下位レベルクラスに論理的に属さないメソッドまたは動作を継承、オーバーライド、または実装させることを回避するため。
for
キーワードなどの言語構造は、クラスインターフェイスとは無関係です。 「混合レベルの抽象化」に関するアドバイスは、メソッドの実装に関してはまったく意味がありません。
質問のタイトルは少し挑発的です。それは、テキストから明らかであるため、「Are for loops allowed in the "Clean Code" set of rules、except for low-level components) "。これが私があなたの質問を解釈する方法です。
私はこれが私にとって非常に興味深い質問だと思います。一見するとそれほど簡単ではありません。ボブマーティンの「クリーンコード」に照らしてこれを解釈するのではなく、ラルフウエストファール(ドイツ語のリファレンス: http:// clean- code-developer.de/ 、Google翻訳をお試しください)。彼が何と呼ぶかについての彼の提案 [〜#〜] ioda [〜#〜] アーキテクチャは、「低レベルと高レベルを混在させない」という原則を極端にします。そして実際、このアーキテクチャでは、「上位のコンポーネント」では「for」ループは見つかりません(条件文のような他の制御構造はありません)-下位レベルでのみです。このアーキテクチャの上位レベルのコンポーネントの目的は、下位レベルのコンポーネントを一緒に「プラグイン」することのみです。
これを本当に極端にすると、すべての関数の構造を次のように変更する必要があります
_ function HighLevelfunction()
sum=0
for i = 1 to upperLimit logic
sum+=LowLevelFunction1(i)
return sum
_
に
_ function LowLevelfunction2( func funcAsParameter)
sum=0
' just for demonstration purposes, think not of reusage here
for i = 1 to upperLimit
sum+=funcAsParameter(i)
return sum
_
最初のバージョンではHighLevelfunction
はLowLevelFunction
に依存し、2番目のバージョンでは_LowLevelfunction2
_は他の関数に依存しなくなりました。 2つ目では、LowLevelfunction2(LowLevelFunction1)
の呼び出しが行われる「より高いレベル」の関数が必要になりますが、これは単なる統合手順であり、必要なより高いレベルでの「for」ループはありません。
ただし、これを実際のプログラムのすべての機能に対して実行することは、おそらく非常に実用的ではなくなります。私(そして他のほとんどのプログラマーもそうだと思います)は、高レベルと低レベルの関数、クラス、またはコンポーネントの間に、より粗い粒度で線を引きます。正しいバランスを見つける必要があり、清潔さのためだけにクリーンなコードを書かないようにしてください。または、ラルフウェストファルの言葉でそれを言うには、 "クリーンアップを船外に持ち出さないでください" です。