タグ付けされた質問 「clean-code」

「クリーンコード」という用語は、簡潔で理解しやすく、プログラマの意図を明確に表すコンピュータプログラミングコードを表すために使用されます。このタグの付いた質問は、クリーンなコードを作成するプロセス、または古い「ダーティ」コードをクリーンなコードにリファクタリングするプロセスに関連しています。

2
ゲッターとセッターを避け、ユーザー情報を表示する
バックグラウンド 私は「クリーンコードブック」を読んでいます。並行して、私は銀行口座などの体操のカタに取り組んでおり、そのルールに固執しています: 体操の9番目のルールは、ゲッターやセッターを使用しないことです。 とても楽しいようで、私はこの原則に同意します。さらに、作者はClean Codeの98〜99ページで、ゲッター/セッターが抽象化を壊し、オブジェクトに問い合わせる必要はないが、オブジェクトに通知する必要があると説明しています。 これは私の心の中で完全に理にかなっており、私はこの原則に完全に同意します。問題は実際に起こります。 環境 たとえば、一部のユーザーをリストし、ユーザーの詳細を表示する必要があるアプリケーションがあります。 私のユーザーは以下で構成されています: -> Name --> Firstname --> String --> Lastname --> String -> PostalAddress --> Street --> String --> PostalCode --> String 問題 どのように私は行うことができ、または私は私だけ(簡単な情報を表示する必要があるときゲッターを避けるために何ができると私はその特定のフィールドに余分な操作を必要としないことを確認する必要があり(単純でのFirstName値を表示します)ランダム)出力サポート? 頭に浮かぶのは 1つの解決策は、 user.getName().getFirstName().getStringValue() これは完全に恐ろしいことであり、体操の多くのルールを破り、デメテルの法則を破ります。 別のものは次のようなものです: String firstName = user.provideFirstnameForOutput(); // That would have called in the user object => …

6
同様に最適化されていない設計を繰り返し繰り返すことをどのように回避しますか?
おそらく多くの人と同じように、設計の問題が頭痛の種になっていることがよくあります。たとえば、問題に直感的に適合し、望ましい利点があるデザインパターン/アプローチがあります。多くの場合、何らかの回避策がないとパターン/アプローチを実装するのが困難になる警告があり、パターン/アプローチの利点が無効になります。多くのパターン/アプローチを繰り返し処理してしまう可能性があります。実際には、簡単な解決策がない実際の状況では、ほぼすべてのパターンに非常に大きな注意事項があるためです。 例: 最近遭遇した実際のものに大まかに基づいた架空の例を紹介します。継承階層が過去のコードのスケーラビリティを妨げていたため、継承ではなくコンポジションを使用したいとしましょう。私はコードをリファクタリングするかもしれませんが、スーパークラス/ベースクラスがサブクラスの機能を単に呼び出す必要があるにもかかわらず、それを回避しようとするいくつかのコンテキストがあることがわかりました。 次善のアプローチは、半分のデリゲート/オブザーバーパターンと半分の構成パターンを実装して、スーパークラスが動作を委任できるようにするか、サブクラスがスーパークラスのイベントを監視できるようにすることです。その場合、クラスを拡張する方法が不明確であるため、クラスの拡張性と保守性が低下します。また、既存のリスナー/デリゲートを拡張するのも難しいです。また、スーパークラスを拡張する方法を確認するために実装を知る必要があるため、情報は十分に隠されていません(コメントを非常に広範囲に使用しない限り)。 したがって、この後は、オブザーバーまたはデリゲートを完全に使用して、アプローチを過度に混同することに伴う欠点を回避することを選択する場合があります。ただし、これには独自の問題があります。たとえば、事実上すべての行動にオブザーバー/デリゲートが必要になるまで、行動の量を増やすためにオブザーバーまたはデリゲートが必要になることに気づく場合があります。1つのオプションは、すべての動作に対して1つの大きなリスナー/デリゲートを持つことですが、実装するクラスは多くの空のメソッドなどで終了します。 それから私は別のアプローチを試すかもしれませんが、それと同じくらい多くの問題があります。それから次のもの、そして次のものなど。 この反復プロセスは、各アプローチが他のアプローチと同じくらい多くの問題を抱えているように見え、一種の設計決定麻痺につながる場合、非常に難しくなります。また、使用する設計パターンやアプローチに関係なく、コードが同じように問題を抱えてしまうことを受け入れるのも困難です。このような状況になった場合、問題自体を再検討する必要があるということですか。この状況に遭遇したとき、他の人は何をしますか? 編集: 私が明確にしたい質問のいくつかの解釈があるようです: OOPは実際にはOOPに固有のものではないことが判明したため、OOPについて質問から完全に除外しました。さらに、OOPについて渡した私のコメントの一部を誤解するのは簡単です。 反復的なアプローチでさまざまなパターンを試す必要があると主張したり、パターンが機能しなくなった場合は破棄したりする必要があると主張する人もいます。これは私が最初に参照するつもりだったプロセスです。これは例からは明らかだと思いましたが、もっと明確にすることができたので、そのために質問を編集しました。

1
実生活でクリーンなコードがどのように見えるかを把握する際の問題
私は現在、Robert C. Martinによる「クリーンコード:アジャイルソフトウェアのクラフトマンシップのハンドブック」を読んで作業しています。著者は、関数が1つのことだけを行うべきであり、したがって比較的短い方法について話します。具体的にはマーティンはこう書いている: これは、ifステートメント、elseステートメント、whileステートメントなど内のブロックが1行の長さであることを意味します。おそらくその行は関数呼び出しでなければなりません。これにより、囲まれた関数が小さく保たれるだけでなく、ブロック内で呼び出された関数にわかりやすい名前を付けることができるため、記録的な価値が追加されます。 これは、関数が入れ子構造を保持するのに十分な大きさであってはならないことも意味します。したがって、関数のインデントレベルは1または2以下にする必要があります。もちろん、これにより機能が読みやすくなり、理解しやすくなります これは理にかなっていますが、私がクリーンなコードと見なしているものの例と矛盾しているようです。たとえば、次の方法を考えます。 public static boolean millerRabinPrimeTest(final int n) { final int nMinus1 = n - 1; final int s = Integer.numberOfTrailingZeros(nMinus1); final int r = nMinus1 >> s; //r must be odd, it is not checked here int t = 1; if (n >= 2047) { …
10 clean-code 

3
クリーンなコードとハイブリッドオブジェクトおよび機能羨望
そのため、最近、コードにいくつかの主要なリファクタリングを行いました。私がしようとした主なことの1つは、クラスをデータオブジェクトとワーカーオブジェクトに分割することでした。これは、とりわけ、Clean Codeの次のセクションに触発されました。 ハイブリッド この混乱は、半分のオブジェクトと半分のデータ構造である不幸なハイブリッドデータ構造につながることがあります。それらには重要な機能を果たす関数があり、パブリック変数またはパブリックアクセサーとミューテーターのいずれかがあり、すべての目的と目的のためにプライベート変数をパブリックにして、他の外部関数がそれらの変数を手続き型プログラムが使用する方法で使用するように誘惑しますデータ構造。 そのようなハイブリッドは、新しい関数を追加することを難しくしますが、新しいデータ構造を追加することも難しくします。彼らは両方の世界で最悪です。それらを作成しないでください。それらは、作者が関数や型からの保護を必要としているかどうか、またはさらに悪いことに無知である混乱した設計を示しています。 最近、私はワーカーオブジェクトの1つ(たまたま、Visitorパターンを実装する)のコードを見て、これを確認しました。 @Override public void visit(MarketTrade trade) { this.data.handleTrade(trade); updateRun(trade); } private void updateRun(MarketTrade newTrade) { if(this.data.getLastAggressor() != newTrade.getAggressor()) { this.data.setRunLength(0); this.data.setLastAggressor(newTrade.getAggressor()); } this.data.setRunLength(this.data.getRunLength() + newTrade.getLots()); } 私はすぐに「!このロジックがであるべき機能の羨望自分自身に言ったData-特に、クラスhandleTradeメソッド。handleTradeとupdateRunする必要があり、常に一緒に起こります」。しかし、「データクラスは単なるpublicデータ構造です。それを始めれば、ハイブリッドオブジェクトになるでしょう!」 何が良いのか、そしてその理由は?どちらを行うかをどのように決定しますか?

5
この問題の純粋に機能的な解決策は、命令と同じくらいクリーンであることができますか?
私はPythonで次のような練習をしています。 多項式は、指数によって指数が決定されるような係数のタプルとして与えられます。例:(9,7,5)は、9 + 7 * x + 5 * x ^ 2を意味します 与えられたxの値を計算する関数を書く 最近関数型プログラミングに夢中になっているので、私は書きました def evaluate1(poly, x): coeff = 0 power = 1 return reduce(lambda accu,pair : accu + pair[coeff] * x**pair[power], map(lambda x,y:(x,y), poly, range(len(poly))), 0) 私はそれを読めないと思うので、私は書きました def evaluate2(poly, x): power = 0 result = 1 return reduce(lambda accu,coeff …

4
応答を処理するためのデザインパターン
ほとんどの場合、特定の関数呼び出しの応答を処理するコードを書いているとき、次のコード構造が得られます。 例:これはログインシステムの認証を処理する関数です class Authentication{ function login(){ //This function is called from my Controller $result=$this->authenticate($username,$password); if($result=='wrong password'){ //increase the login trials counter //send mail to admin //store visitor ip }else if($result=='wrong username'){ //increase the login trials counter //do other stuff }else if($result=='login trials exceeded') //do some stuff }else if($result=='banned ip'){ //do …

7
条件を重複してチェックするのは悪いスタイルですか?
コードの中で、特定の条件を何度もチェックしていることがよくあります。 簡単な例を挙げましょう。「a」で始まる行、「b」で始まる行、およびその他の行を含むテキストファイルがあり、実際には最初の2種類の行のみを処理したいとします。私のコードは次のようになります(Pythonを使用しますが、擬似コードとして読み取ります)。 # ... clear_lines() # removes every other line than those starting with "a" or "b" for line in lines: if (line.startsWith("a")): # do stuff elif (line.startsWith("b")): # magic else: # this else is redundant, I already made sure there is no else-case # by using clear_lines() # ... …

1
コメントの「TILT」とはどういう意味ですか?
私はRobert C. MartinのClean Codeを読んTILTでいますが、このフレーズは一部のコードサンプルに不可解に表示されています。例(ちなみにJavaです): ... public String errorMessage() { switch (status) { case ErrorCode.OK: // TILT - Should not get here. return ""; case ErrorCode.UNEXPECTED_ARGUMENT: return "Unexpected argument"; case ErrorCode.MISSING_ARGUMENT: return "Missing argument"; ... } ... コンテキストから、TILT到達できない状態であり、コンパイラを満たすためにのみ含まれている状態を指定していると思います(たとえば、上記のコードでは、状態がの場合はエラーメッセージが表示されないためTILT、ErrorCode.OKケースに表示されますOK)が、よく分かりません。 誰かがTILT/の意味が何であるか知っていますか?

7
クラスを細かくしすぎていませんか?単一責任原則はどのように適用されるべきですか?
私は3つの基本的な手順を含む多くのコードを記述しています。 どこかからデータを取得します。 そのデータを変換します。 そのデータをどこかに置きます。 私は通常、それぞれの設計パターンに触発された3種類のクラスを使用します。 ファクトリー-あるリソースからオブジェクトを構築します。 メディエーター-ファクトリーを使用するには、変換を実行してから、司令官を使用します。 司令官-そのデータを別の場所に配置します。 私のクラスは非常に小さく、多くの場合単一の(パブリック)メソッドです。たとえば、データの取得、データの変換、作業の実行、データの保存などです。これはクラスの急増につながりますが、一般的にはうまく機能します。 私がテストに来るときに苦労しているのは、結局は密結合テストになります。例えば; 工場-ディスクからファイルを読み取ります。 Commander-ファイルをディスクに書き込みます。 もう1つがないとテストできません。ディスクの読み取り/書き込みを行うための追加の「テスト」コードを作成することもできますが、それから繰り返します。 .Netを見ると、Fileクラスは別のアプローチをとっており、(私の)ファクトリーとコマンダーの責任を組み合わせています。Create、Delete、Exists、Readの機能がすべて1か所にあります。 .Netの例をたどって、特に外部リソースを扱う場合は、クラスを一緒に結合する必要がありますか?結合されたコードですが、意図的です。テストではなく、元の実装で発生します。 ここでの問題は、単一責任の原則をやや熱心に適用したことですか?読み取りと書き込みを担当する個別のクラスがあります。特定のリソース(システムディスクなど)の処理を担当する結合クラスがある場合。

6
抽象クラスにはどのコードを含める必要がありますか?
最近、抽象クラスの使用について困っています。 時々、抽象クラスが事前に作成され、派生クラスがどのように機能するかのテンプレートとして機能します。つまり、多かれ少なかれ、それらはいくつかの高レベルの機能を提供しますが、派生クラスによって実装される特定の詳細を除外します。抽象クラスは、いくつかの抽象メソッドを配置することにより、これらの詳細の必要性を定義します。そのような場合、抽象クラスは設計図、機能の高レベルの説明、またはそれと呼ぶもののように機能します。単独では使用できませんが、高レベルの実装から除外された詳細を定義するために専門化する必要があります。 場合によっては、いくつかの「派生」クラスの作成後に抽象クラスが作成されることがあります(親/抽象クラスがそこにないため、それらはまだ派生されていませんが、私が何を意味するか知っています)。これらの場合、抽象クラスは通常、現在の派生クラスに含まれるあらゆる種類の共通コードを配置できる場所として使用されます。 上記の観察をしたので、私はこれらの2つのケースのどちらがルールであるべきか疑問に思っています。派生クラスすべてに共通しているという理由だけで、抽象クラスに詳細を吹き込む必要がありますか?高レベルの機能の一部ではない一般的なコードがありますか? たまたま派生クラスに共通しているからといって、抽象クラス自体には意味がないコードが存在する必要がありますか? 例を挙げましょう。抽象クラスAにはメソッドa()と抽象メソッドaq()があります。メソッドaq()は、派生クラスABとACの両方で、メソッドb()を使用します。b()をAに移動する必要がありますか?もしそうなら、誰かがAだけを見ている場合(ABとACがそこにないふりをしよう)、b()の存在はあまり意味がありません!これは悪いことですか?誰かが抽象クラスを見て、派生クラスにアクセスせずに何が起こっているのかを理解できる必要がありますか? 正直なところ、この質問をしている時点で、派生クラスを調べなくても意味のある抽象クラスを書くことは、クリーンなコードとアーキテクチャの問題だと信じがちです。anyあらゆる種類のコードのダンプのように機能する抽象クラスのアイデアが、すべての派生クラスで一般的に発生するのを嫌う あなたはどう思いますか/練習しますか?

6
switchステートメントでswitchを減らす方法は?
データベースから2人に基づいて挨拶文を作成する方法を作成しています。 4つのパラメーターがあります。2つの名前(name1およびname2)および2つの性別(genderおよびgender2)です。 性別の組み合わせごとに、ある種の異なる出力があります。 たとえば、性別1がM(男性)で、性別2もであるM場合、出力は次のようになります。 Dear Sir name1 and Sir name2, 現時点では、私のスイッチは次のようになります。 switch(gender1){ case 'M': switch(gender2){ case 'M': printf("Dear Sir %s and Sir %s", name1, name2); break; case 'W': printf("Dear Sir %s and Madame %s", name1, name2); break; case 'R': ... } break; case 'W': switch(gender2){ case 'M': printf("Dear Madame %s …

3
iOS開発のWebサービスからデータを取得するためにHTTPリクエストを作成するメソッドをどこに配置すればよいですか?
私のiOSアプリケーションにModel Carがあり、名前、年、値などのパラメーターがWebサービスからフェッチされ、リストに自動車のデータが入力されます。 非同期でサーバーに行き、車の配列を返すメソッドをどこに置くべきですか(このメソッドはすでにJSONをCar配列に変換しています)? 私の現在のアプローチは、HttpClientを受信して​​(クライアントをモックするユニットテストを実行できるように)Carクラスの静的メソッドであり、車のNSArrayを返しますが、これは良いですか? この状況で皆さんは何をしましたか? 私は最近、クラスは1つのことだけを行うべきであるというクリーンなコードを読み始めたので心配です。現在の方法では、2つのことを行うように見えます(Carに関する情報を保持し、Carのリストを取得します)。

7
メソッドがfalseを返すかどうかの確認:結果を一時変数に割り当てるか、メソッド呼び出しを条件付きで直接配置しますか?
ifステートメントでtrueまたはfalseの値を返すメソッドを呼び出すのは良い習慣ですか? このようなもの: private void VerifyAccount() { if (!ValidateCredentials(txtUser.Text, txtPassword.Text)) { MessageBox.Show("Invalid user name or password"); } } private bool ValidateCredentials(string userName, string password) { string existingPassword = GetUserPassword(userName); if (existingPassword == null) return false; var hasher = new Hasher { SaltSize = 16 }; bool passwordsMatch = hasher.CompareStringToHash(password, existingPassword); return …

2
一連のステップを実行するためのフォールスルースイッチ
私のプログラムは、最初から最後まで一連のステップを実行する必要があります。ただし、異なる入力に基づいて開始点は異なります。たとえば、最初のステップから最後まで実行されるもの、2番目のステップから最後まで実行されるもの、3番目から最後まで実行されるものなどがあります。 シンプルなデザインが必要ですが、現在は次のようなフォールスルースイッチを使用しています。 switch (step) { case 1: //do the 1st step //fall through, so no break here case 2: //do the 2nd step //fall through case 3: //do the 3rd step //fall through ... } それは機能しますが、フォールスルーコードは常に私を不快にします。それを行うためのより良い簡単な方法はありますか?

2
…Helperまたは…Managerクラスを回避する方法
プロジェクトにはかなりの数のヘルパークラスがあります。これは悪いことだと読んだことがありますが、「ヘルパー」がサフィックスとして間違っていると思います。例を挙げましょう。 まず、Userクラスがあります。GetSuggestedFriends()ユーザーのための方法が必要です。提案された友達のリストをUserクラスから除外するためのロジックを保持したいので、肥大化しません。現在、コンストラクターでFriendshipHelperを受け取るがありUserます。友達候補を取得するためのロジックが含まれているので、を呼び出すことができますmyUser.FriendshipHelper.GetSuggestedFriends()。 元々FriendshipHelperは静的メソッドのみがあり、Userオブジェクトはそれぞれに渡されていました。今、クラスを最初から作成している場合は、それを呼び出すかもしれませんFriendshipManager-友達の追加や削除なども行います。 ...Managerただし、クラスが悪いことも読みました。私はこのクラスを何と呼ぶべきですか?または、これは「不良コード」ですか?友達候補、現在の友達、友達の追加と削除のロジックはどこにあるべきですか?きっとすべてが巨大なUserクラスにいるわけではありませんか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.