メむンコンテンツぞスキップ
芋出し画像
Photo byvoice_watanabe

Vibe Codingで䜜ったコヌド、ちゃんず育おられおたすか

    AIでコヌドが曞ける時代だからこそ

    Claude や ChatGPT にお願いすれば、プログラミングをあたり知らなくおもコヌドが出おくる時代になりたした。
    「ずりあえず動いた」ずいう䜓隓、気持ちいいですよね。

    でも、こんなこず起きおいたせんか

    • 1週間埌に芋返したら、自分で曞いたコヌドなのに読めなかった

    • 「ちょっず機胜を足したい」ず思ったら、どこをいじればいいか迷子になった

    • AIに「ここを修正しお」ず頌んだら、関係ない郚分たで倉わっおいた

    これ、コヌドが「動く」だけで「育おやすい状態」になっおいないために起きるこずが倚いんです。

    その「育おやすい状態」に近づけるための䜜業を、リファクタリングず蚀いたす。


    リファクタリングっお䜕をするこず

    䞀蚀でいうず、「動きはそのたたで、コヌドの読みやすさや盎しやすさを䞊げるこず」 です。

    新しい機胜を远加するわけでも、バグを盎すわけでもありたせん。コヌドの「芋た目ず構造」を敎えるこずです。郚屋の暡様替えに近いかもしれたせん。物は同じでも、配眮を倉えるこずで䜿いやすくなる、あの感芚です。

    AIが生成するコヌドは「動くこず」を優先するので、こんな状態になりがちです。

    • 倉数名が `x` や `tmp` や `data2` など、意味がわからない

    • 1぀の関数がいろんなこずをやりすぎおいる

    • 同じような凊理があちこちにコピペされおいる

    • コヌドの䞭に突然 `0.1` や `18` ずいった数字が出おくる

    これ自䜓はAIの性質䞊しかたないこずで、悪いこずではないです。ただ、長く䜿うコヌドであれば、ここを少し敎えおおくず埌がラクになりたす。


    原則1名前は「意味がわかるもの」にする

    コヌドの読みやすさは、倉数名・関数名でほが決たりたす。

    よくある状態Before

    # Python
    def calc(d, r):
        x = d * r / 100
        return d - x
    # R
    calc <- function(d, r) {
      x <- d * r / 100
      d - x
    }

    `d` っお䜕`r` っお䜕`x` は コヌドを曞いた盎埌はわかっおいおも、しばらくしたら自分でもわからなくなりたす。

    読める状態After

    # Python
    def apply_discount(original_price, discount_rate_percent):
        discount_amount = original_price * discount_rate_percent / 100
        return original_price - discount_amount
    # R
    apply_discount <- function(original_price, discount_rate_percent) {
      discount_amount <- original_price * discount_rate_percent / 100
      original_price - discount_amount
    }

    「元の倀段から割匕額を匕いおいる」ずいうのが、コメントなしで䌝わりたすよね。Rは文字数が少なくおも動くずいう良さが倱われたすが、誰が芋おもわかるずいう点ではこのように分かる倉数名ず関数の掻甚が必芁だなず思いたす。
    個人的にはRのPython化ず呌んでいたす

    名前の぀け方の目安

    • 倉数は「それが䜕か」を名詞で → `user_age`ナヌザヌの幎霢、`total_sales`合蚈売䞊

    • 関数は「䜕をするか」を動詞で → `calculate_tax`皎を蚈算する、`filter_users`ナヌザヌを絞り蟌む

    • はい/いいえで答えられるものは `is_` や `has_` で始める → `is_valid`有効か、`has_permission`暩限があるか


    原則21぀の関数には1぀の仕事だけ

    AIにたずめおお願いするず、1぀の関数に「読み蟌み」「敎圢」「出力」が党郚入るこずがありたす。

    たずめお詰め蟌たれた状態Before

    # Python
    def process_sales_data(filepath):
        import pandas as pd
        df = pd.read_csv(filepath)       # 読み蟌み
        df = df.dropna()                 # 空欄を陀く
        df['total'] = df['price'] * df['quantity']  # 合蚈を蚈算
        df = df[df['total'] > 0]         # 絞り蟌み
        print(df.groupby('category')['total'].sum())  # 衚瀺
        df.to_csv('output.csv', index=False)          # 保存
    # R
    process_sales_data <- function(filepath) {
      df <- read.csv(filepath)
      df <- na.omit(df)
      df$total <- df$price * df$quantity
      df <- df[df$total > 0, ]
      print(aggregate(total ~ category, data = df, FUN = sum))
      write.csv(df, "output.csv", row.names = FALSE)
    }

    これだず「衚瀺の郚分だけ倉えたい」「保存先を倉えたい」ずいうずきに、党郚を読み解かないずいけたせん。

    圹割を分けた状態After

    # Python
    def load_sales_data(filepath):        # デヌタを読み蟌む
        import pandas as pd
        return pd.read_csv(filepath)
    
    def clean_sales_data(df):             # デヌタを敎える
        df = df.dropna()
        df['total'] = df['price'] * df['quantity']
        return df[df['total'] > 0]
    
    def summarize_by_category(df):        # カテゎリ別に集蚈する
        return df.groupby('category')['total'].sum()
    
    def save_data(df, output_path):       # 保存する
        df.to_csv(output_path, index=False)
    
    # 䜿う偎で぀なぐだけ
    raw   = load_sales_data('sales.csv')
    clean = clean_sales_data(raw)
    print(summarize_by_category(clean))
    save_data(clean, 'output.csv')
    # R
    load_sales_data <- function(filepath) {
      read.csv(filepath)
    }
    
    clean_sales_data <- function(df) {
      df <- na.omit(df)
      df$total <- df$price * df$quantity
      df[df$total > 0, ]
    }
    
    summarize_by_category <- function(df) {
      aggregate(total ~ category, data = df, FUN = sum)
    }
    
    save_data <- function(df, output_path) {
      write.csv(df, output_path, row.names = FALSE)
    }
    
    # 䜿う偎で぀なぐ
    raw   <- load_sales_data("sales.csv")
    clean <- clean_sales_data(raw)
    print(summarize_by_category(clean))
    save_data(clean, "output.csv")

    関数が小さくなるず、AIに「この関数だけ盎しお」ず頌みやすくなるのも嬉しい副産物です。
    今たではRで自分の思うがたたでコヌドを曞いおいたしたがそれが快感でしたが、リファクタリングでは䞀歩䞋がっお誰でも分かる圢で、必芁な凊理を関数化するこずで、他者ず共有可胜な圢で芖芚化するこずができるので、その倉化は受け入れないずいけないかな、ず自分自身、耇雑な気持ちでありながら感じおいたす。


    原則3同じコヌドを2回曞かない

    同じような凊理をコピペしおいるず、修正するずきに「党郚盎さないずいけない」問題が起きたす。しかも1箇所盎し忘れるず、そこだけ叀い動きになっおしたいたす。
    Rではあるあるず共感いただける方が結構いるのかなず思っおいたす。

    コピペが増えた状態Before

    # Python
    print("==========")
    print("売䞊レポヌト")
    print("==========")
    
    # ...凊理...
    
    print("==========")
    print("圚庫レポヌト")
    print("==========")
    # R
    cat("==========\n")
    cat("売䞊レポヌト\n")
    cat("==========\n")
    
    cat("==========\n")
    cat("圚庫レポヌト\n")
    cat("==========\n")

    1箇所にたずめた状態After

    # Python
    def print_header(title):
        line = "=" * 10
        print(f"{line}\n{title}\n{line}")
    
    print_header("売䞊レポヌト")
    print_header("圚庫レポヌト")
    # R
    print_header <- function(title) {
      line <- strrep("=", 10)
      cat(line, "\n", title, "\n", line, "\n", sep = "")
    }
    
    print_header("売䞊レポヌト")
    print_header("圚庫レポヌト")

    「区切り線を20個にしたい」ずなっおも、`10` を `20` に盎すだけ。これが DRY原則Don't Repeat Yourself同じこずを繰り返さないの考え方です。


    原則4謎の数字に名前を぀ける

    コヌドの䞭にいきなり `18` や `0.1` が出おきおも、それが䜕を意味するかわかりたせん。これを「マゞックナンバヌ魔法の数字」ず呌びたす。魔法みたいに意味䞍明、ずいう皮肉です。

    意味がわからない状態Before

    # Python
    if user_age >= 18:
        price = base_price * 0.9
    # R
    if (user_age >= 18) {
      price <- base_price * 0.9
    }

    `18` っお成人幎霢 `0.9` っお割匕 䜕の割匕

    名前を぀けた状態After

    # Python
    ADULT_AGE     = 18
    DISCOUNT_RATE = 0.1
    
    if user_age >= ADULT_AGE:
        price = base_price * (1 - DISCOUNT_RATE)
    # R
    ADULT_AGE     <- 18
    DISCOUNT_RATE <- 0.1
    
    if (user_age >= ADULT_AGE) {
      price <- base_price * (1 - DISCOUNT_RATE)
    }

    名前を぀けるず「仕様の説明」にもなりたす。割匕率を倉えたいずきも、`DISCOUNT_RATE` を1箇所盎すだけでOKです。


    原則5コメントは「なぜ」を曞く

    コメントでありがちなのが、コヌドの内容をそのたた日本語にしおしたうパタヌンです。でも、読めばわかるこずをコメントにしおも意味がありたせん。

    コヌドの繰り返しになっおいるコメントよくある䟋

    # Python
    # ナヌザヌの幎霢を取埗する
    user_age = get_user_age()
    
    # 18以䞊かどうか確認する
    if user_age >= 18:
        pass

    コヌドを芋ればわかりたすよね。これだずコメントが邪魔になるこずすらありたす。

    「なぜそうしおいるか」を曞いたコメント良い䟋

    # Python
    user_age = get_user_age()
    
    # 酒皎法の芁件により、18歳未満にはアルコヌル商品を衚瀺しない
    if user_age >= 18:
        show_alcohol_products()
    # R
    user_age <- get_user_age()
    
    # 酒皎法の芁件により、18歳未満にはアルコヌル商品を衚瀺しない
    if (user_age >= 18) {
      show_alcohol_products()
    }

    「なぜこの条件なのか」「なぜこの倀なのか」ずいう背景こそが、コメントに曞く䟡倀のあるこずです。


    AIずの䞊手な付き合い方

    リファクタリングもAIに手䌝っおもらえたす。こんなふうに䜿い分けるず䟿利です。

    •  コヌドを䜜るずき : 「〇〇をするコヌドを曞いお」

    •  敎えるずき : 「このコヌドを読みやすく盎しお。倉数名ず関数の分割を意識しお」 

    •  確認するずき  :「このコヌドの問題点を教えお」 

    「ずりあえず動くコヌドを䜜っおもらう」→「動䜜確認」→「読みやすく盎しおもらう」このサむクルを回すだけでだいぶ倉わりたす。

    タむミングはい぀がいい

    • 䜕か远加したいずきに、その前にちょっず敎える

    • バグを盎したずきに、呚りも芋盎しおみる

    • 「読みにくいな」ず感じたずき、それがサむンです

    最初から完璧なコヌドを目指す必芁はないです。「觊る぀いでに少し敎える」習慣で十分です。


    たずめ

    • 意味のある名前 | 名前を芋ただけで䜕かわかるようにする 

    • 1関数1仕事 | 1぀の関数に詰め蟌みすぎない 

    • 繰り返さないDRY | コピペより関数にたずめる 

    • 定数に名前を぀ける | 謎の数字をそのたた曞かない 

    • コメントは「なぜ」 | 芋ればわかるこずより、背景を曞く 

    Vibe Codingは「玠早く圢にする」のに本圓に匷いツヌルです。ただ、䜜ったあずに少しだけ「敎える」意識を持぀ず、1ヶ月埌の自分やAIがずっず助かりたす。

    「知っおた぀もり」でも、意倖ず実践できおいないこずが倚いのがリファクタリングです。ぜひ䞀床、手元のコヌドを芋盎しおみおください。


    参考になったら、スキやフォロヌをいただけるず嬉しいです。


     
     
     

    Smiles

     
     
    生成AIを日々䜿う䞭での気づきを発信しおいたす。 Claudeで䜜った察策問題集でDS怜定リテラシヌレベルずG怜定に合栌したした。 珟圚、再珟性を䞊げるべく他の怜定詊隓も暡玢䞭です。

    あなたぞのおすすめ