コードの匂いは、Java コード内の潜在的な問題を示し、保守性、可読性、パフォーマンスに影響を与えます。 常にバグがあるわけではありませんが、バグに対処することでコードベースをクリーンで効率的に保つことができます。この記事では、5 つの一般的な Java コードの匂いを調べ、例、説明、改善された解決策を示します。
問題: メソッドが長すぎると、可読性、テスト、メンテナンスが妨げられます。ヘルパー メソッドを使用する場合でも、複数の抽象レベルを組み合わせると単一責任原則 (SRP) に違反します。
例:
<code class="language-java">public void processOrder(Order order) { validateOrder(order); calculateDiscount(order); updateInventory(order); generateInvoice(order); sendNotification(order); }</code>
processOrder
には無関係なタスク (検証、割引計算、在庫更新、請求書発行、通知) が混在しているため、意図しない結果を招くことなく変更することが困難です。
解決策: より小さく、焦点を絞ったメソッドにリファクタリングします。コマンド パターンやパイプライン パターンなどのデザイン パターンは、モジュール性を強化します。
リファクタリングされたコード (コマンド パターン):
<code class="language-java">interface OrderCommand { void execute(Order order); } class ValidateOrderCommand implements OrderCommand { public void execute(Order order) { /* Validation logic */ } } // ... other commands (ApplyDiscountCommand, etc.) class OrderProcessor { List<OrderCommand> commands; public OrderProcessor(List<OrderCommand> commands) { this.commands = commands; } public void processOrder(Order order) { for (OrderCommand command : commands) { command.execute(order); } } } // Usage List<OrderCommand> commands = List.of(new ValidateOrderCommand(), new ApplyDiscountCommand(), ...); OrderProcessor processor = new OrderProcessor(commands); processor.processOrder(new Order());</code>
利点: モジュール性の向上、独立したテストとコマンドの再利用、新しいステップの簡単な追加。
問題: 「神クラス」はあまりにも多くの責任を処理するため、結合度が高く、保守性が低下します。
例:
<code class="language-java">public class OrderManager { public void createOrder() { /* Implementation */ } public void updateOrder() { /* Implementation */ } public void deleteOrder() { /* Implementation */ } public void validatePayment() { /* Implementation */ } public void sendInvoice() { /* Implementation */ } }</code>
解決策: 責任をより小規模で集中的なクラスに分割します。
リファクタリングされたコード:
<code class="language-java">public class OrderService { public void createOrder() { /* Implementation */ } // ... other order-related methods } public class PaymentService { public void validatePayment() { /* Implementation */ } } public class NotificationService { public void sendInvoice() { /* Implementation */ } }</code>
利点: 結合の減少、モジュール性の向上、メンテナンス、テストの容易化、独立した拡張。
問題: リテラル数値を直接使用すると、コードの明瞭さが低下し、変更の危険が生じます。
例:
<code class="language-java">public double calculateDiscount(double totalAmount) { return totalAmount > 1000 ? totalAmount * 0.1 : totalAmount; }</code>
解決策: リテラル数値を名前付き定数に置き換えます。
リファクタリングされたコード:
<code class="language-java">private static final double DISCOUNT_THRESHOLD = 1000; private static final double DISCOUNT_RATE = 0.1; public double calculateDiscount(double totalAmount) { return totalAmount > DISCOUNT_THRESHOLD ? totalAmount * DISCOUNT_RATE : totalAmount; }</code>
利点: 可読性の向上、更新中のエラーのリスクの軽減、ビジネス ロジックの明確化。
問題: メソッドまたはクラス間でコードを繰り返すと、不整合が発生し、メンテナンスの悩みが生じます。
例:
<code class="language-java">public double calculateTax(double amount) { return amount * 0.18; } public double calculateDiscount(double amount) { return amount * 0.1; }</code>
解決策: 共通ロジックを再利用可能なメソッドに抽象化します。
リファクタリングされたコード:
<code class="language-java">private double applyRate(double amount, double rate) { return amount * rate; } public double calculateTax(double amount) { return applyRate(amount, 0.18); } public double calculateDiscount(double amount) { return applyRate(amount, 0.1); }</code>
利点: 冗長性を排除し、一貫性を確保し、変更と拡張を簡素化します。
問題: 多くのパラメータを持つメソッドは読みにくく、理解しにくく、呼び出し中にエラーが発生しやすくなります。
例:
<code class="language-java">public void processOrder(Order order) { validateOrder(order); calculateDiscount(order); updateInventory(order); generateInvoice(order); sendNotification(order); }</code>
解決策: パラメータをオブジェクト内にカプセル化するか、ビルダー パターンを使用します。
リファクタリングされたコード:
<code class="language-java">interface OrderCommand { void execute(Order order); } class ValidateOrderCommand implements OrderCommand { public void execute(Order order) { /* Validation logic */ } } // ... other commands (ApplyDiscountCommand, etc.) class OrderProcessor { List<OrderCommand> commands; public OrderProcessor(List<OrderCommand> commands) { this.commands = commands; } public void processOrder(Order order) { for (OrderCommand command : commands) { command.execute(order); } } } // Usage List<OrderCommand> commands = List.of(new ValidateOrderCommand(), new ApplyDiscountCommand(), ...); OrderProcessor processor = new OrderProcessor(commands); processor.processOrder(new Order());</code>
利点: 可読性と拡張性が向上します。パラメータを追加する場合、メソッド シグネチャを変更する必要はありません。
コードの臭いに積極的に対処すると、より大きな設計上の問題が防止され、技術的負債が軽減され、より堅牢で保守しやすい Java アプリケーションが実現されます。 よりクリーンで効率的なコードを作成するには、DRY (Don't Reply Yourself) と SRP (Single Responsibility Principle) の原則を覚えておいてください。
以上がJava のよくあるコードの臭いとその修正方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。