コンテンツにスキップ

V/ユースケース

出典: フリー教科書『ウィキブックス(Wikibooks)』
< V

コードの構造化

[編集]

モジュール設計

[編集]

モジュールは単一の責任を持つように設計します。以下は適切なモジュール分割の例です:

// user/types.v - ユーザー関連の型定義
module user

pub struct User {
    id   int
    name string
mut:
    email string
}

// user/validation.v - バリデーションロジック
module user

pub fn validate_email(email string) bool {
    return email.contains('@')
}

// user/storage.v - ストレージ関連の操作
module user

pub fn save(user User) !int {
    // データベースへの保存処理
}

ファイル構成

[編集]

プロジェクトのファイル構成は以下のような階層構造を推奨します:

project/
├── src/
│   ├── main.v
│   ├── config/
│   │   ├── types.v
│   │   └── loader.v
│   ├── user/
│   │   ├── types.v
│   │   └── service.v
│   └── api/
│       ├── handlers.v
│       └── middleware.v
├── tests/
└── v.mod

エラー処理

[編集]

エラーの粒度

[編集]

エラーは適切な粒度で定義し、具体的な情報を含めます:

// 悪い例
fn process_user(user User) ! {
    return error('処理に失敗しました')
}

// 良い例
fn process_user(user User) ! {
    if user.age < 0 {
        return error('年齢は0以上である必要があります: ${user.age}')
    }
    if user.name.len == 0 {
        return error('名前は必須です')
    }
    // 処理の実装
}

エラーの集約

[編集]

関連するエラーは適切に集約して返します:

struct ValidationError {
    field string
    message string
}

fn validate_user(user User) ![] ValidationError {
    mut errors := []ValidationError{}
    
    if user.name.len == 0 {
        errors << ValidationError{
            field: 'name'
            message: '名前は必須です'
        }
    }
    if user.age < 0 {
        errors << ValidationError{
            field: 'age'
            message: '年齢は0以上である必要があります'
        }
    }
    
    if errors.len > 0 {
        return errors
    }
    return []ValidationError{}
}

パフォーマンス最適化

[編集]

メモリ効率

[編集]

大きなデータ構造を扱う場合は参照を使用します:

// メモリ効率の良い実装
fn process_large_data(data &[]int) {
    // データの参照を使用した処理
}

// 可変な参照が必要な場合
fn modify_large_data(mut data &[]int) {
    // データの変更
}

並行処理の適切な使用

[編集]

並行処理は適切なタイミングで使用します:

// 重い処理は並行実行
fn process_items(items []Item) []Result {
    mut handles := []thread Result{}
    
    for item in items {
        handles << go process_item(item)
    }
    
    return handles.wait()
}

// 軽い処理は直列実行
fn validate_items(items []Item) []bool {
    return items.map(is_valid(it))
}

テスト

[編集]

テストの構造

[編集]

テストは準備、実行、検証の3段階で構造化します:

fn test_user_registration() {
    // 準備
    mut db := setup_test_db()
    user := User{
        name: 'test'
        email: 'test@example.com'
    }
    
    // 実行
    result := register_user(mut db, user)!
    
    // 検証
    assert result.id > 0
    assert db.find_user_by_email('test@example.com')! == user
}

テストデータの管理

[編集]

テストデータは再利用可能な形で管理します:

// test_data.v
module test_helpers

pub fn create_test_user() User {
    return User{
        name: 'test'
        email: 'test@example.com'
    }
}

pub fn create_test_users(count int) []User {
    return []User{len: count, init: create_test_user()}
}

セキュリティ

[編集]

入力検証

[編集]

すべてのユーザー入力は適切に検証します:

fn process_user_input(input string) ! {
    // 文字列長の制限
    if input.len > 1000 {
        return error('入力が長すぎます')
    }
    
    // 特殊文字のエスケープ
    safe_input := html_escape(input)
    
    // 適切な型への変換
    value := safe_input.int() or {
        return error('数値として無効な入力です')
    }
    
    // 値の範囲チェック
    if value < 0 || value > 100 {
        return error('値は0から100の間である必要があります')
    }
}

機密情報の管理

[編集]
機密情報は適切に保護します:
struct Credentials {
private:
    password string
pub:
    username string
}

fn (c &Credentials) validate() !bool {
    if c.username.len == 0 {
        return error('ユーザー名は必須です')
    }
    if c.password.len < 8 {
        return error('パスワードは8文字以上である必要があります')
    }
    return true
}

ドキュメンテーション

[編集]

コードコメント

[編集]

重要な関数やタイプには適切なドキュメントコメントを付けます:

// User represents a system user with basic information.
// It is used throughout the application for user management.
pub struct User {
pub:
    id int // Unique identifier
    name string // Display name
mut:
    email string // Primary email address
}

// save_user persists the user information to the database.
// It returns the user ID on success, or an error if the operation fails.
pub fn save_user(user User) !int {
    if !validate_user(user)! {
        return error('Invalid user data')
    }
    // 保存処理の実装
}

モジュールドキュメント

[編集]

各モジュールの役割を明確に記述します:

// module: auth
// このモジュールは認証と認可に関する機能を提供します。
; // 主な機能:
// - ユーザー認証
// - セッション管理
// - アクセス制御
module auth

// Token は認証トークンを表します。
pub struct Token {
    value string
    expires_at time.Time
}

メンテナンス性

[編集]

依存関係の管理

[編集]

外部依存は最小限に抑え、必要な場合は適切にラップします:

// database/wrapper.v
module database

// DatabaseWrapper は外部データベースライブラリのラッパーです
struct DatabaseWrapper {
mut:
    conn &DatabaseConnection
}

// query は安全なクエリ実行を提供します
pub fn (db &DatabaseWrapper) query(sql string, params ...string) ![]Row {
    // 接続状態の確認
    if !db.is_connected() {
        return error('データベース接続が確立されていません')
    }
    
    // パラメータのバリデーション
    for param in params {
        if param.len == 0 {
            return error('空のパラメータは許可されません')
        }
    }
    
    // クエリの実行
    return db.conn.query(sql, ...params)
}

コードの再利用

[編集]

共通の機能は再利用可能な形で実装します:

// utils/validation.v
module utils

pub fn validate_email(email string) bool {
    return email.contains('@') && email.contains('.')
}

pub fn validate_phone(phone string) bool {
    return phone.len >= 10 && phone.all(it.is_digit())
}

// validators/common.v
module validators

import utils

pub fn validate_contact_info(email string, phone string) !bool {
    if !utils.validate_email(email) {
        return error('無効なメールアドレスです')
    }
    if !utils.validate_phone(phone) {
        return error('無効な電話番号です')
    }
    return true
}