paint-brush
コードの怪しい部分を見つける方法 [パート XLVI]@mcsee
635 測定値
635 測定値

コードの怪しい部分を見つける方法 [パート XLVI]

Maximiliano Contieri10m2023/11/27
Read on Terminal Reader

長すぎる; 読むには

カウボーイのプログラマーはベストプラクティスに従いません。 彼らはチームの提案に従いません。 カウボーイ コーディングは、保守が難しくエラーが発生しやすいコードにつながる可能性があるため、一般にソフトウェア開発における専門的ではない危険なアプローチであると考えられています。
featured image - コードの怪しい部分を見つける方法 [パート XLVI]
Maximiliano Contieri HackerNoon profile picture

コードが臭いのは、編集または改善できる可能性が高いためです。


これらの臭いのほとんどは、何かが間違っている可能性があることを示唆するものにすぎません。したがって、それ自体を修正する必要はありません… (ただし、検討する必要があります。)

以前のコードの匂い

以前のすべてのコード匂い (パート I ~ XLV) はここで見つけることができます。


続けましょう...


コードの匂い 226 - 混合優先順位

またしても墜落した宇宙船。別のソフトウェアの問題


TL;DR: ソフトウェアを設計してテストします。ハードウェアよりも安い

問題点

  • 単射故障
  • 予期せぬ欠陥

ソリューション

  1. 正確なシミュレーションを作成する
  2. フォールトトレラントなソフトウェアを作成する

コンテクスト

ルナ 25 号は2023 年 8 月 19 日に月面に墜落しました。


インドのチャンドラヤーン3号が月の南極に軟着陸する4日前。


フォレンジック分析の結果、命令がバスを共有しており、優先順位が正しく設定されていないことが判明しました。


宇宙船にはソフトウェア障害の長い歴史があります。

サンプルコード

間違っている

class TaskManager: def __init__(self): self.tasks = [] def add_task(self, task, priority): self.tasks.append((task, priority)) def execute_tasks(self): # No sorting for task, _ in self.tasks: task.execute() class Task: def __init__(self, name): self.name = name def execute(self): print(f"Executing task: {self.name}") task_manager = TaskManager() highPriorityTask = Task("Slow down") mediumPriorityTask = Task("Take Photos") reviveKlaatu = Task("Klaatu barada nikto") # unsorted task_manager.add_task(mediumPriorityTask, 2) task_manager.add_task(highPriorityTask, 1) task_manager.add_task(reviveKlaatu, 3) task_manager.execute_tasks()

class TaskManager: def __init__(self): self.tasks = [] def add_task(self, task, priority): self.tasks.append((task, priority)) def execute_tasks(self): # Sort tasks by priority (high to low) self.tasks.sort(key=lambda x: x[1], reverse=True) for task, _ in self.tasks: task.execute() class Task: def __init__(self, name): self.name = name def execute(self): print(f"Executing task: {self.name}") task_manager = TaskManager() highPriorityTask = Task("Slow down") mediumPriorityTask = Task("Take Photos") reviveKlaatu = Task("Klaatu barada nikto") # unsorted task_manager.add_task(mediumPriorityTask, 2) task_manager.add_task(highPriorityTask, 1) task_manager.add_task(reviveKlaatu, 3) task_manager.execute_tasks()

検出

  • [x]マニュアル

これはデザインの匂いです

タグ

  • 信頼性

結論

ソフトウェアコンポーネントを作成し、実際の条件と非現実の条件をシミュレートします

関係

コードの匂い 198 - 隠された仮定

より詳しい情報

免責事項

コードの匂いは私の意見です。


分析エンジンには、何かを生み出すためのふりはありません。それは私たちが知っていることなら何でも実行できます…しかし、それは科学そのものに間接的かつ相互的な影響を与える可能性があります。


エイダ・ラブレス

ソフトウェアエンジニアリングの名言


コードの匂い 227 - カウボーイコーディング

カウボーイのことはハリウッド映画に任せましょう。


TL;DR: チーム プログラマーとしてコードを作成する

問題点

  • 可読性
  • 信頼性の低いコード
  • 人材管理の問題
  • 協調性の欠如

ソリューション

  1. プロフェッショナルなコードを書きます。


  2. 暗号化されていない宣言的な名前を使用してください。

コンテクスト

カウボーイのプログラマーはベストプラクティスに従いません。


彼らはチームの提案に従いません。


カウボーイ コーディングは、保守が難しくエラーが発生しやすいコードにつながる可能性があるため、一般にソフトウェア開発における専門的ではない危険なアプローチであると考えられています。


カウボーイプログラマーは良い人たちです。ただし、グループで作業することはできません

サンプルコード

間違っている

# Very simple example # Compute the sum of two numbers without any structure or best practices. num1 = input("Enter the first number: ") num2 = input("Enter the second number: ") # WARNNING!!!! Don't remove the line below !!!!! # (Unpleasant comment) res = num1 + num2 # (No data type checking or error handling) print("The sum is: " + result) # (No validation or formatting) # (No good names, no functions, no error handling, no testing, # no version control, and no structure.)

def add_numbers(): try: firstAddend = float(input("Enter the first number: ")) secondAddend = float(input("Enter the second number: ")) total = firstAddend + secondAddend return total except ValueError: print("Invalid input. Please enter valid numbers.") return None def main(): total = add_numbers() if total is not None: print("The sum is: {:.2f}".format(sum)) if __name__ == "__main__": main()

検出

  • [x]マニュアル


環境ルールを設定して、このようなコーディング慣行を防止し、チーム構築を強制することができます。

例外

  • 非常に小さな個人プロジェクト

タグ

  • 宣言的

結論

ソフトウェア開発はチームワークです。

関係

コードの匂い 06 - 賢すぎるプログラマー

コードの匂い 02 - 定数とマジックナンバー

コードの匂い 105 - コメディアンのメソッド

より詳しい情報

https://www.linkedin.com/pulse/software-development-cowboy-coding-hakan-atbaş/

クレジット

UnsplashTaylor Brandonによる写真


コンピュータの危険は、コンピュータが最終的には人間と同じくらい賢くなることではなく、その間に私たちが中途半端にコンピュータに会うことに同意してしまうことだ。

バーナード・アビシャイ


コード スメル 228 - ファイルごとに複数のクラス

複数のクラスは混乱します。


TL;DR: 関心事の分離の原則とファイル構成に従う

問題点

  • コード構成
  • カップリング
  • 自動読み込みの問題
  • デバッグ
  • バージョン管理とマージの競合

ソリューション

  1. ファイルごとに 1 つのクラスを宣言する


  2. 名前のスコープを使用する

コンテクスト

ファイル システムを使用してクラスを宣言する言語では、ファイルごとに 1 つのクラスを持つことが一般的にベスト プラクティスと考えられています。


このアプローチは、コードの構成と保守性を向上させ、潜在的な問題を軽減するのに役立ちます。


プロジェクト構造内の別のディレクトリに名前空間を整理できます。


こうすることで、単一ファイルで複数のクラスを宣言する問題を回避しながら、論理的で効率的なコードベースを維持できます。

サンプルコード

間違っている

<? namespace MyNamespace; class Class1 { public function sayHello() { echo "Hello from Class1!\n"; } } class Class2 { public function sayHello() { echo "Hello from Class2!\n"; } }

<? namespace MyNamespace; class Class1 { public function sayHello() { echo "Hello from Class1!\n"; } }
 <? namespace MyNamespace; class Class2 { public function sayHello() { echo "Hello from Class2!\n"; } }

検出

  • [x]自動

多くの標準がこのルールを適用しています

タグ

  • カップリング

結論

コードを整理して、既知の標準に従ってください。

関係

コードの匂い 48 - 標準のないコード

より詳しい情報

クレジット

UnsplashMarjan Blanによる写真


要件や設計がなければ、プログラミングは空のテキスト ファイルにバグを追加する技術です。


ルイス・シグレー


コードの匂い 229 - お役所仕事

コードが複雑になりすぎます。


TL;DR: 偶発的な複雑さと官僚主義を避ける

問題点

  • 偶然の複雑さ
  • 可読性
  • 単射故障

ソリューション

  1. MAPPERを使用して現実世界のオブジェクトに責任を割り当てます。

コンテクスト

コードの「お役所仕事」の匂いは、コードベースの理解や保守を困難にする不必要な複雑さ、官僚主義、または過剰な構成に関連している可能性があります。

サンプルコード

間違っている

class VotingSystem: def __init__(self, config): self.config = config def validate_voter(self, voter_id): if self.config['voter_verification_enabled']: # Code to verify the voter's identity goes here def cast_vote(self, voter_id, candidate): if self.config['voting_enabled']: # Code to record the vote goes here def generate_vote_report(self): if self.config['generate_report']: # Code to generate a voting report goes here def audit_voting_system(self): if self.config['audit_enabled']: # Code to perform an audit of the voting system goes here # ... other voting-related methods ... # Usage config = { 'voter_verification_enabled': True, 'voting_enabled': False, 'generate_report': False, 'audit_enabled': True } voting_system = VotingSystem(config) # Voter validation, voting, report generation, # and auditing are handled based on the configuration.

class VoterVerification: def verify_voter(self, voter_id): # Code to verify the voter's identity goes here class VotingMachine: def cast_vote(self, voter_id, candidate): # Code to record the vote goes here class VoteReporter: def generate_report(self): # Code to generate a voting report goes here class VotingAuditor: def audit_voting_system(self): # Code to perform an audit of the voting system goes here # Usage voter_verification = VoterVerification() voting_machine = VotingMachine() vote_reporter = VoteReporter() voting_auditor = VotingAuditor() # Voter verification, vote casting, report generation, # and auditing are handled separately.

検出

  • [x]半自動

一部のツールは、不必要な責任を負ってオブジェクトが肥大化していると推測できます。

タグ

  • ブローター

結論

開発者はどの機能がアクティブであるかを判断するために複雑な構成をナビゲートする必要があるため、お役所仕事のコードの匂いは明らかです。


これにより、不必要な複雑さが増すだけでなく、システムの整合性に影響を与える可能性のある構成ミスの可能性も高まります。

関係

コードの匂い 54 - アンカーボート

免責事項

コードの匂いは私の意見です。

クレジット

Unsplash爆発による写真


ソフトウェアの誤謬: ソフトウェアが機能していて、何も変更しなければ、引き続き動作し続けます。

ジェシカ・カー


コード スメル 230 - シュレーディンガー コード

あなたのコードは死んでいて生きています。


TL;DR: 競合状態を注意深く確認してください

問題点

ソリューション

  1. 競合状態を回避する


  2. グローバル変数を避ける


  3. 適切な同期を使用する

コンテクスト

シュレーディンガー コードは、同時に 2 つの異なる状態になれるコードですが、コードの状態は実行されるまで決定されません。


これは、コードに競合状態が含まれている場合、またはコードが他のスレッドまたはプロセスによって変更される可能性のあるグローバル変数の状態に依存している場合に発生する可能性があります。

サンプルコード

間違っている

import threading cats_alive = 0 def thread_1(): cats_alive += 1 def thread_2(): cats_alive -= 1 if cats_alive > 0: feedThem() # The value of cats_alive is indeterminate, # so the code can be in either of the two states: # # 1. cats_alive > 0 and feedThem() is called. # 2. cats_alive <= 0 and feedThem() is not called.

import threading lock = threading.Lock() cats_alive = 0 def thread_1(): with lock: cats_alive += 1 def thread_2(): with lock: cats_alive -= 1 if cats_alive > 0: feedThem() # With the lock, the two threads cannot access # the `cats_alive` variable at the same time. # This means that the value of `cats_alive` is always determined, # and the program will not exhibit Schrödinger code behavior.

検出

  • [x]マニュアル

同時実行コードのコードレビューを行う

タグ

  • 同時実行性
  • グローバル

結論

シュレーディンガー コードを回避するには、競合状態を回避し、他のスレッドまたはプロセスによって変更される可能性のあるグローバル変数の状態に依存しないようにします。


コードでグローバル変数を使用する必要がある場合は、それが正しく同期されていることを確認してください。

関係

コードの匂い 198 - 隠された仮定

コード スメル 32 - シングルトン

コード スメル 60 - グローバル クラス

クレジット

UnsplashYerlin Matuによる写真


プログラマにとって最も避けたいことは、内部状態をいじることです。

アラン・ケイ


来週はさらに5つの香りを追加します。