>  기사  >  웹 프론트엔드  >  코드 냄새: 무시할 수 없는 코드베이스의 경고 신호

코드 냄새: 무시할 수 없는 코드베이스의 경고 신호

Patricia Arquette
Patricia Arquette원래의
2024-10-07 14:20:29695검색

Code Smells: Warning Signs in Your Codebase You Can

코더라면 "엉뚱한" 느낌을 받는 코드를 접했을 가능성이 높습니다. 유지 관리, 이해 또는 확장이 더 어렵습니다. 코드 냄새라고 알려진 코드베이스의 이러한 일반적인 경고 신호는 무언가 잘못되었음을 나타냅니다. 악취가 썩은 것을 가리키는 것처럼, 코드 ​​냄새는 코드 설계 또는 구현에 잠재적인 문제가 있음을 암시합니다.

자세히 알아보기 전에 다음 사항을 명확히 합시다.

"냄새"라는 용어는 문제가 있는 코드를 악취에 비유한 비유입니다. 코드 냄새를 구성하는 요소는 다음에 따라 주관적일 수 있습니다.

  • 사용하는 프로그래밍 언어
  • 귀하의 팀이 따르는 개발 방법론
  • 개발자의 개인 취향

코드 냄새에 관심을 가져야 하는 이유는 무엇입니까?

코드 냄새를 무시하는 것은 자동차 정비를 미루는 것과 같습니다. 오늘은 문제가 되지 않을 수도 있지만 시간이 지나면 심각한 고장으로 이어질 수 있습니다. 주의해야 할 이유는 다음과 같습니다.

  1. 유지관리성

    부풀어오르거나 불분명한 코드는 유지 관리하기가 악몽입니다. 디버깅 속도가 느려지고 버그가 발생할 가능성이 높아집니다.

  2. 확장성

    냄새나는 코드로 인해 애플리케이션 확장이 어려워집니다. 코드베이스가 커짐에 따라 근본적인 문제로 인해 기하급수적인 문제가 발생할 수 있습니다.

  3. 기술부채

    코드 냄새를 무시하는 것은 빚을 쌓는 것과 같습니다. 결국에는 시간이 많이 걸리는 재작성이나 디버깅의 형태로 이자와 함께 갚아야 합니다.


공통 코드 냄새(및 해결 방법)

가장 일반적인 코드 냄새와 이를 정리하는 전략을 살펴보겠습니다.

1. 부풀어오르는 코드

? 긴 메소드 또는 클래스

메서드나 클래스가 너무 길어지면 이해, 테스트, 유지 관리가 어려워집니다.

예:

function processOrder(order) {
    validateOrder(order);
    calculateDiscount(order);
    applyTaxes(order);
    updateInventory(order);
    sendConfirmation(order);
}


이 방법은 괜찮아 보이지만 너무 많은 작업을 수행하므로 따라가기가 어렵습니다.

해결책: 긴 메서드를 더 작은 단일 목적 함수로 나눕니다.


function processOrder(order) {
    validateOrder(order);
    applyDiscountsAndTaxes(order);
    finalizeOrder(order);
}

function applyDiscountsAndTaxes(order) {
    calculateDiscount(order);
    applyTaxes(order);
}


? 과도한 댓글

과도한 주석은 코드가 설명이 필요하지 않다는 의미일 수 있습니다.

예:

// Calculate the total price after applying the discount
let totalPrice = price - (price * discount);


해결책: 자체 문서화가 가능하도록 코드를 리팩터링합니다.


let totalPrice = applyDiscount(price, discount);



2. 객체 지향적 학대

? 전환 설명

유형별 동작을 처리하는 Switch 문은 객체 지향 프로그래밍에서 다형성으로 대체될 수 있는 경우가 많습니다.

예:

function getArea(shape) {
    switch(shape.type) {
        case 'circle':
            return Math.PI * shape.radius ** 2;
        case 'square':
            return shape.side * shape.side;
    }
}


해결책: 다형성을 사용하여 모양별 동작을 처리합니다.


class Shape {
    getArea() {
        throw "Must be implemented by subclass";
    }
}

class Circle extends Shape {
    constructor(radius) {
        super();
        this.radius = radius;
    }

    getArea() {
        return Math.PI * this.radius ** 2;
    }
}

class Square extends Shape {
    constructor(side) {
        super();
        this.side = side;
    }

    getArea() {
        return this.side * this.side;
    }
}


? 임시 필드

특정 시나리오에서만 사용되는 필드는 수업을 복잡하게 만들고 불필요한 복잡성을 초래할 수 있습니다.

해결책: 가능하면 이러한 필드를 로컬 변수나 매개변수로 이동하거나 책임을 여러 클래스로 분할하세요.


3. 강성

? 다양한 변화

관련 없는 이유로 단일 클래스를 수정해야 한다면 이는 해당 클래스가 너무 많은 일을 하려고 한다는 신호입니다.

해결책: 클래스를 더 작고 집중적인 단위로 나누어 단일 책임 원칙을 적용하세요.

? 산탄총 수술

변경으로 인해 여러 클래스를 수정해야 하는 경우 이는 모듈성이 좋지 않다는 신호입니다. 이는 리팩토링이나 기능 추가를 어렵게 만들 수 있습니다.

해결책: 변경 사항이 흩어진 이유를 파악하고 관련 로직을 그룹화하여 리팩터링합니다.


4. 불필요한 복잡성

? 중복 코드

동일한 코드가 여러 위치에 있으면 버그가 발생하고 유지 관리가 어려워질 수 있습니다.

예:

function calculateTotalPrice(price, tax) {
    return price + (price * tax);
}

function calculateDiscountedPrice(price, discount, tax) {
    let discountedPrice = price - (price * discount);
    return discountedPrice + (discountedPrice * tax);
}


해결책: 공통 로직을 재사용 가능한 메소드로 추출합니다.


function calculatePrice(price, tax, discount = 0) {
    let discountedPrice = price - (price * discount);
    return discountedPrice + (discountedPrice * tax);
}


? 데드코드

데드 코드는 더 이상 사용되지 않는 기능입니다. 코드베이스가 복잡해지고 개발자에게 혼란을 줄 수 있습니다.

해결책: 사용하지 않는 코드를 정기적으로 제거하여 코드베이스를 깔끔하고 간결하게 유지하세요.


5. 타이트한 커플링

? 특집 부러움

메서드가 자신의 데이터 대신 다른 개체의 데이터에 크게 의존하는 경우 이는 긴밀한 결합의 신호입니다.

Example:

function getDiscount(customer) {
    return customer.purchaseHistory.totalAmount > 1000 ? 0.1 : 0;
}


Solution: Consider moving the behavior to the object itself.


class Customer {
    getDiscount() {
        return this.purchaseHistory.totalAmount > 1000 ? 0.1 : 0;
    }
}


? Inappropriate Intimacy

Classes that rely too heavily on each other’s internal details create unnecessary dependencies.

Solution: Enforce stricter encapsulation and reduce reliance on internal data.


Additional Code Smells to Watch Out For

  • Magic Numbers Replace unexplained numbers with named constants to improve readability and maintainability.

Example:


  const SALES_TAX = 0.07;
  let total = price + (price * SALES_TAX);


  • Deep Nesting

    Simplify deeply nested loops or conditionals for better readability. Consider early returns or extracting methods.

  • Long Parameter Lists

    Refactor methods that take many parameters by using parameter objects or reducing the method’s responsibility.


How to Deal with Code Smells

Code smells don’t mean your code is broken, but they are early indicators that your design may need improvement. Here's how you can deal with them:

  1. Refactoring

    The most effective way to deal with code smells is through refactoring—improving the internal structure of your code without changing its external behavior.

  2. Incremental Changes

    You don’t have to fix everything at once. Start with small, focused refactorings, targeting the smelliest areas of your code.

  3. Testing

    Before you refactor, ensure that your code has adequate tests in place. This helps you catch regressions and verify that the refactored code behaves as expected.


Final Thoughts

Recognizing and addressing code smells is crucial for maintaining healthy, scalable, and maintainable code. Think of it as preventative care—cleaning up these smells early will save you time, effort, and headaches down the line. Keep an eye out for these common warning signs, and make refactoring a regular part of your coding process!

위 내용은 코드 냄새: 무시할 수 없는 코드베이스의 경고 신호의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.