{}const=>[]async()letfn</>var
開発基礎

コードのリファクタリング:既存のコードを改善して読みやすくする方法

リファクタリングとは何か、既存のコードをどのように改善するかを学びます。初心者向けのJavaScriptとPythonの実例、基本的なテクニック、ツール、安全なリファクタリングのルール。

К

Kodik

著者

2分で読める

想像してみてください。半年前に書いたコードを開き、data1data2temp変数を持つ200行の関数で何が起こっているのか理解できません。聞き覚えがありますか?これは、コードをリファクタリングする必要があるという合図です。

リファクタリングとは何ですか?

リファクタリングとは、コードの外部動作を変更することなく、コードの内部構造を変更するプロセスです。これは、アパートを整理するようなものです。物は同じままですが、見つけやすくなります。

リファクタリングはバグを修正したり、新しい機能を追加したりすることではないことを理解することが重要です。これは、将来の作業を容易にするために、既存のコードの品質を向上させることです。

🔥 10万人以上の学生が参加中

理論を読むのに疲れた?
コーディングの時間だ!

Kodik — 実践でプログラミングを学ぶアプリ。AIメンター、インタラクティブなレッスン、実際のプロジェクト。

🤖 AI 24時間
🎓 修了証
💰 無料
🚀 始める
今日参加

コードをリファクタリングする必要がある場合

リファクタリングを始める時期が来たという明確な兆候がいくつかあります。コードの重複は典型的な例です。同じブロックを異なる場所にコピーする場合、これは個別の関数に移動する最初の候補です。あまりにも多くの異なることをする長い関数も、より小さく、より理解しやすい部分に分割する必要があります。

変数や関数の名前が悪いと、認知的負荷がかかります。変数が x または arr と呼ばれる場合、その意味を覚えておく必要があります。そして、activeUserscalculateTotalPrice のような名前は、その意味が明確です。

多くのネストされた条件を持つ複雑なロジックは、コードを迷路に変えます。3つ以上のネストレベルifが表示されている場合は、リファクタリングを検討することをお勧めします。

リファクタリングの基本的なテクニック

関数の抽出

これは最も一般的なテクニックです。コードの一部を取得し、わかりやすい名前の別の関数に移動します。

// リファクタリング前
function processOrder(order) {
    // 検証
    if (!order.items || order.items.length === 0) {
        throw new Error('Order is empty');
    }
    if (!order.userId) {
        throw new Error('No user specified');
    }
    
    // 合計の計算
    let total = 0;
    for (let item of order.items) {
        total += item.price * item.quantity;
    }
    
    // 割引の適用
    if (order.promoCode) {
        total *= 0.9;
    }
    
    return total;
}

// リファクタリング後
function processOrder(order) {
    validateOrder(order);
    const total = calculateTotal(order.items);
    return applyDiscount(total, order.promoCode);
}

function validateOrder(order) {
    if (!order.items || order.items.length === 0) {
        throw new Error('Order is empty');
    }
    if (!order.userId) {
        throw new Error('No user specified');
    }
}

function calculateTotal(items) {
    return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}

function applyDiscount(total, promoCode) {
    return promoCode ? total * 0.9 : total;
}

これで、processOrder関数は本のように読み取られます。注文を検証し、金額を計算し、割引を適用します。各操作は、その関数にカプセル化されています。

名前の変更

良い名前は成功の半分です。変数はその中に何が格納されているかを反映し、関数はそれが何をするかを反映する必要があります。

# まで
def calc(a, b, c):
    return a * b * c / 100

# 後
def calculate_discount_amount(price, quantity, discount_percent):
    return price * quantity * discount_percent / 100

条件の簡素化

複雑な条件は、わかりやすい名前の関数に移動するか、早期返却を使用できます。

// まで
function canUserEdit(user, document) {
    if (user.isAuthenticated) {
        if (user.role === 'admin' || document.authorId === user.id) {
            if (!document.isLocked) {
                return true;
            }
        }
    }
    return false;
}

// 後
function canUserEdit(user, document) {
    if (!user.isAuthenticated) return false;
    if (document.isLocked) return false;
    
    return user.role === 'admin' || document.authorId === user.id;
}

マジックナンバーを定数に置き換える

マジックナンバーは、文脈なしでは意味がわからない値です。

# まで
if user.age >= 18:
    grant_access()

# 後
MINIMUM_AGE_FOR_ACCESS = 18

if user.age >= MINIMUM_AGE_FOR_ACCESS:
    grant_access()

クラスのリファクタリング

オブジェクト指向のコードを扱うとき、多くのクラスがあまりにも多くのことを行うことがよくあります。単一責任の原則は、クラスに変更の理由が1つだけであるべきであるということです。

# 前:クラスが多すぎる
class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email
    
    def save_to_database(self):
        # データベースに保存するロジック
        pass
    
    def send_welcome_email(self):
        # メール送信のロジック
        pass
    
    def generate_report(self):
        # レポート生成のロジック
        pass

# 後:責任を分担
class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

class UserRepository:
    def save(self, user):
        # データベースに保存するロジック
        pass

class EmailService:
    def send_welcome_email(self, user):
        # メール送信のロジック
        pass

class UserReportGenerator:
    def generate(self, user):
        # レポート生成のロジック
        pass

安全なリファクタリングのルール

テストなしのリファクタリングはロシアンルーレットのようなものです。コードを変更する前に、その機能をカバーするテストがあることを確認してください。テストがない場合は、リファクタリングの前にテストを書いてください。

小さな一歩を踏み出しましょう。一度にすべてを書き換えようとしないでください。小さなリファクタリングを1つ行い、テストを実行して、すべてが機能していることを確認してから、次のリファクタリングに進むことをお勧めします。

頻繁にコミットする。リファクタリングの成功した各ステップは個別のコミットです。何かがうまくいかない場合は、ロールバックできます。

リファクタリングすべきではない場合

リファクタリングは目的ではありません。コードをそのままにしておく方が良い場合もあります。廃棄される可能性のあるプロトタイプに取り組んでいる場合、深いリファクタリングは意味がありません。コードが長年安定して動作しており、誰も触れていない場合は、リスクを冒さない方が良い場合があります。

また、理解していないコードをリファクタリングしないでください。まず、その仕組みを理解し、テストを書いてから、構造を改善してください。

リファクタリングツール

最新の IDE は、リファクタリングを大幅に容易にします。PyCharm、VS Code、または WebStorm には、変数と関数の自動名前変更、メソッドの抽出、関数シグネチャの変更があります。これらのツールを使用して、エラーを回避するのに役立ちます。

JavaScript の ESLint や Python の Pylint などのリンターは、コードの問題点を検出するのに役立ちます。重複、複雑すぎる関数、未使用の変数を示します。

開発文化の一部としてのリファクタリング

技術的な負債を蓄積するのではなく、定期的に小さなリファクタリングを行うのが最善のアプローチです。ボーイスカウトのルールは、コードをあなたが使用する前よりもクリーンにしておくことです。関数を使用していますか?名前を改善してください。重複が見えますか?一般的な関数に移動します。

コードレビューは、リファクタリングの絶好の機会です。同僚の新鮮な視点は、コードの作成者が見逃したことをしばしば気づかせます。

最初からクリーンなコードを書く方法を学びたいですか?

アプリケーション コディック プログラミングの第一歩を踏み出す人たちのために特別に作成されました。ここでは単に理論を学ぶだけでなく、実際にプロジェクトを作成しながら、知識をすぐに実践に応用できます。コースは、初日から実際に機能し、誇りに思えるコードを書けるように構成されています。コードを書く方法を学ぶと、リファクタリングによってコードをさらに改善する方法を学ぶことができます。

私たちの Telegramチャンネル!

私たちは、誰もが最も単純なものから専門的なものまで、あらゆる質問をすることができる開発者のフレンドリーなコミュニティを持っています。毎日、基礎から高度なテクニックまで、開発のトップテーマを分析しています。ここでは尋ねることを恥ずかしく思わず、常に理解するのを助けてくれます。一緒に学ぶのはもっと面白いです!

🎯先延ばしをやめよう

記事は気に入った?
実践の時間だ!

Kodikでは読むだけでなく、すぐにコードを書く。理論 + 実践 = 本当のスキル。

即座に実践
🧠AIがコードを説明
🏆修了証

登録不要 • カード不要