【日本人エンジニア必携】英語命名規則の決定版

この記事は[Nuco Advent Calendar 2023](https://qiita.com/advent-calendar/2023/nuco)の24日目の記事です。

:::note inf
弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています！興味をお持ちいただける方は、[こちら](https://www.recruit.nuco.co.jp/?qiita_item_id=94bd9e5d5dfd665ad044)まで。
:::

## はじめに
英語での適切な命名は、コードの可読性や保守性を向上させるために重要です。適切な命名規則を守ることがコードの理解や共有において不可欠です。
英語での命名規則を学び、適切な命名を行うことで、コードの読みやすさや保守性を向上させ、チーム全体でのコードの理解を促進する手助けとなります。
この記事では、日本人エンジニアが英語での命名規則を理解し、適切な命名を行うための指針を提供します。

## 命名フローチャート
#### 変数
![スクリーンショット 2023-12-14 19.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958239/9e900dda-eec9-0feb-2790-a03cd6ec4467.png)
#### 関数
![スクリーンショット 2023-12-14 19.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958239/60ca0c05-c169-476a-9ec7-46ef3292c021.png)
#### クラス
![スクリーンショット 2023-12-01 20.14.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958239/c2c9f4f9-b003-4a8e-f2bd-e7c2b4764e80.png)


## 1. 変数
### 1-1. boolean
#### 1-1-1. 存在するかどうかのフラグ
名詞 + exists
```python
# ユーザーIDが存在するかどうか
user_id_exists

# True　→　存在する
# False　→　存在しない
```
#### 1-1-2. 表示・非表示
show + 名詞
```python
# 購入履歴を表示するかどうか
show_purchase_histories

# True　→　表示する
# False　→　表示しない
```
#### 1-1-3. 機能ON/OFFフラグ
名詞 + enabled
```python
# 自動音量調節機能ON/OFF
auto_volume_adjustment_enabled

# True　→　自動音量調節機能ON
# False　→　自動音量調節機能OFF
```
#### 1-1-4. 持つ/含むかどうかのフラグ
has/contains + 名詞
```python
# 購入済み商品を含むか
has_purchased_items

# True　→　購入済み商品を含む
# False　→　購入済み商品を含まない
```
#### 1-1-5. 基本形
is + 形容詞
```python
# 空かどうか
is_empty

# True　→　空である
# False　→　空ではない
```
### 1-2. booleanではない
#### 1-2-1. 日時
動詞 + at/on
```python
# atの場合は日時
# 作成日時
created_at

# onの場合は日付
# 削除日
deleted_on
```
#### 1-2-2. その他の変数
名詞の複数形
```python
# リストなど複数のデータが集まったもの

# ユーザーIDのリスト
user_ids
# クリック履歴のリスト
clicked_histories
```
形容詞 + 名詞
```python
# 形容詞により説明を加える

# 新しいコンテンツ
new_contents
```
動詞の受動態 or ing形 + 名詞
```python
# 受動態やing形でもよい

# クリックされたコンテンツ
clicked_contents
# 待機中の処理
waiting_process
```
名詞 + 名詞
```python
# 商品の状態
item_condition

# condition_of_itemなどとすると長くなってしまう
```
名詞 + without/before/after + ~
```python
# 許可のないユーザー
user_without_permission

# 発送前の商品
item_before_shipping

# 発送後の商品数
item_quantity_after_shipping
```

## 2. 関数
### ・基本形
動詞のみor動詞+名詞
```python
# クラス内で定義されており、目的語が明白である場合などには動詞のみでよい
# メッセージを作成する
class MessageCreator:
    
    ...
    
    def create(self):
        ...
        return message
# create_messageとしない

# 目的語を明示する場合
# 文字列を結合する
def join_strings(first_text:str, second_text: str)
```

### 2-1. 取得
#### 2-1-1. オブジェクトから値を取得
get
```python
class User:
    def __init__(
        self,
        user_id: int,
        name: str,
        age: int,
        ):
        self.user_id = user_id
        self.name = name
        self.age = age

    # ユーザーの名前を取得
    def get_name(self):
        return self.name
```
select (配列の場合)
```python
# 未読のメッセージを取得
def select_unread_messages(messages: list[Message])
```
#### 2-1-2. DBなど別の場所から値を取得する
fetch
```python
# データベースから商品データを取得
def fetch_items()
```
search(検索というニュアンスの時。複数検索の場合)
```python
# 商品のリストから指定した色・値段の商品を検索
def search_items(items: list[Item], color: str, price: int)
```
find(1つあることが期待される取得の場合)
```python
# ファイルやディレクトリの中から、指定した名前のファイルを探す
def find_file(path, filename):
# データベースの中から、指定した条件に合致するレコードを見つける
def find_record(database, condition):
```
#### 2-1-3. ファイルを読み込む
load
```python
# ローカルのファイルを読み込む
def load_file(file_path: str)
```
read(1行のみ読み込む時)
```python
# 読み込んだファイルから1行だけ取得する
def read_line(file: File, row_number: int)
```
#### 2-1-4. 条件付きの取得
filter
```python
# コンテンツのリストからお気に入り登録されたものを取得する
def filter_bookmarked_contents(contents: list(Content))
```
extract
```python
# 辞書のリストから指定したキーの値だけを抽出
def extract_values(dicts: list[dict], key: str)
```

### 2-2. 変更
#### 2-2-1. データを変換
to + 名詞
```python
class User:
    def __init__(
        self,
        user_id: int,
        name: str,
        age: int,
        ):
        self.user_id = user_id
        self.name = name
        self.age = age

    # Userオブジェクトから辞書に変換
    def to_dict(self):
        return {'user_id': self.user_id, 'name': self.name, 'age': self.age}
```
toggle(状態を切り替える)場合
```python
class Item:
    def __init__(
        self,
        item_id: int,
        name: str,
        number: int,
        is_purchased: bool
        ):
        self.item_id = item_id
        self.name = name
        self.number = number
        self.is_purchased = is_purchased

    # 購入済みかどうかのフラグを切り替える
    def toggle_purchase_status(self):
        self.is_purchased = not self.is_purchased
```
#### 2-2-2. 情報の更新（データベースのレコード変更など）
update
```python
# 支払い合計金額の更新
def update_total_payment()
```
#### 2-2-3. 部分的な修正
modify
```python
# 文字列の一部を修正
def modify_text(text: str, terget_str: str, new_str: str)
```
#### 2-2-4. 新しいデータで置き換える
change
```python
class User:
    def __init__(
        self,
        user_id: int,
        name: str,
        age: int,
        ):
        self.user_id = user_id
        self.name = name
        self.age = age

    # ユーザーの名前を変更
    def change_name(self, new_name: str):
        self.name = new_name
```
#### 2-2-5. 順序や文字の入れ替え
replace
```python
# アイテムリストの中の古いアイテムを新しいアイテムと入れ替える
def replace_old_items(items: list[Item], new_item: Item, old_item: Item)
```
#### 2-2-6. 元の状態に復元する
restore
```python
# 状態を元の状態に戻す
def restore_state()
```
#### 2-2-7. 誤ったデータを直す
correct
```python
def correct_event_start_date(events: list[Event], correct_date: date)
```
#### 2-2-8. 有効化する
enable
```python
class Config:
    def __init__(
        self,
        auto_volume_adjustment_enabled: bool
        ...
        ):
        self.auto_volume_adjustment_enabled = auto_volume_adjustment_enabled
        ...

    # 自動音量調節機能をONにする
    def enable_auto_volume_adjustment():
        self.auto_volume_adjustment_enabled = True
```
#### 2-2-9. 無効化する
disable
```python
def __init__(
        self,
        auto_volume_adjustment_enabled: bool
        ...
        ):
        self.auto_volume_adjustment_enabled = auto_volume_adjustment_enabled
        ...

    # 自動音量調節機能をOFFにする
    def disable_auto_volume_adjustment():
        self.auto_volume_adjustment_enabled = False
```
#### 2-2-10. ルールに沿って適用する
apply
```python
# 検証ルールを適用する
def apply_validation()
```

### 2-3. 追加
#### 2-3-1. DBにデータを加える
add
```python
# テーブル（データベース）に新しいレコードを追加
def add_record()    # addはデータベース以外にも、コレクションやリストなどデータ構造に追加する
```
insert
```python
# テーブル（データベース）に新しいレコードを追加
def insert_record()    # データベースにデータを挿入する
```
#### 2-3-2. 配列にデータを加える
append
```python
# 商品一覧の末尾にアイテムを追加する
def append_item(items: list[Item], additional_item: Item)
```
prepend
```python
# 商品一覧の先頭にアイテムを追加する
def prepend_item(items: list[Item], additional_item: Item)
```
insert
```python
# 商品一覧の任意の場所にアイテムを追加する
def insert_item(items: list[Item], additional_item: Item, index: int)
```
#### 2-3-3. 複数のデータを結合する
merge
```python
# 商品リストをひとまとめにする
def merge_items(kids_items: list[Item], senior_items: list[Items])
```

### 2-4. 作成
#### 2-4-1. ルールに基づいて何かを生成する（機械がプログラムのとおりに何かを作り出す場合など）
generate
```python
# ランダムにパスワードを作成する
def generate_password()
```
#### 2-4-2. 新しく作る(何もないところに新しく何かを生み出す)
create
```python
# 指定したカラムを持つ空のデータフレームを作成
def create_empty_dataframe(columns: list[str])
```
### 2-5. 削除
#### 2-5-1. データを削除する場合（もとに戻せない）
delete
```python
class User:
    def __init__(
        self,
        user_id: int,
        name: str,
        age: int,
        ):
        self.user_id = user_id
        self.name = name
        self.age = age
    
    
    def delete(slef):
        del self
```
#### 2-5-2. データをアクセス可能な場所から取り除く場合（もとに戻せる可能性あり）
remove
```python
# 権限のないユーザーを削除する
def remove_denied_user
```
#### 2-5-3. 中身を空にする場合（親となるオブジェクトや変数自体は消えない）
clear
```python
ブックマークリストの中身を空にする
def clear_bookmarks
```
#### 2-5-4. オブジェクトを完全に破棄する場合（再利用されたり、読み取られたりしないように破却）
destroy/dispose
```python
# セッションを完全に破棄する
def destroy_session()
# メモリを完全に開放する
def dispose_memory()
```

### 2-6. 検査
#### 2-6-1. 要件や性能を満たしているかを調べる場合
validate
```python:example.py
# 限度額を超えていないかどうかを検査
def validate_price(item: Item, max_price: int)
```
#### 2-6-2. 正しく動作しているか確かめる場合
verify
```python
# 認証を確認する
def verify_authentication()
```
#### 2-6-3. 状態の確認
[変数のboolian参照](https://qiita.com/drafts/4b06db0953053d41c4a0/edit#1-1-boolean)

### 2-7. 許可
#### 2-7-1. 許可する・権限を与える
allow
```python
# アクセスを許可する
def allow_access()
```
#### 2-7-2. 申請を承認する
accept
```python
# 申請を承認する
def accept_application()
```
#### 2-7-3. ユーザーに権限を持たせる
grant
```python
# ユーザーにテキスト編集権限を与える
def grant_user_edit_text()
```

### 2-8. 禁止
#### 2-8-1. 申請を退ける
refuse/reject/deny
```python
# 申請を退ける
def refuse_application()    # acceptの反対として使われる。
def reject_application()    # acceptの反対として使われる。refuseよりも強い禁止。
def deny_application()    # allowの反対として使われる。
```
#### 2-8-2. 許可を取り消す
revoke
```python
# 許可を取り消す
def revoke_permission()
```


## 3. クラスの命名
### ・基本形
名詞を使う
```python
class User
class Content
class Item
```
### 3-1. ２つの単語を繋げてクラスを作る
形容詞 + 名詞 or 名詞 + 名詞
```python
# 添付ファイル
class AttachedFile
# クリック履歴
class ClickHistory
```

### 3-2. データソースを扱う
#### 3-2-1. Server-Client
名詞 + Client
```python
# BigQueryとの通信や操作を担う
class BigQueryClient
```
#### 3-2-2. APIを叩くためのゲートウェイ
名詞 + Gateway
```python
# タイムラインに関連する操作を管理する
class TimelineGateway
```
#### 3-2-3. DBにデータを保存
名詞 + Store
名詞 + Storage
```python
# コンテンツの保存を担う
class ContentStore
class ContentStrage
```
#### 3-2-4. キャッシュする
名詞 + Cache
```python
# 履歴をキャッシュする
class ClickHistoryCache
```
#### 3-2-5. ログの保存場所
名詞 + Log
```python
# APIの利用ログを保存
class APIUsageLog
```
#### 3-2-6. 履歴の保存場所
名詞 + History
```python
# クリック履歴を保存
class ClickHistory
```
#### 3-2-7. 設定データの保存場所
名詞 + Configuration/Preference/Setting
```python
# 推薦システムの設定を保存
class RecommendationConfiguration
class RecommendationPreference
class RecommendationSetting
```

### 3-3. データを加工する
#### 3-3-1. データの絞込
名詞 + Filter
```python
# 条件に合わないコンテンツを除外
class ContentFilter
```
#### 3-3-2. データを抽出
名詞 + Extractor
```python
# 条件に合ったコンテンツを抽出
class ContentExtructor
```
#### 3-3-3. データを整形
名詞 + Formatter
```python
# メッセージの整形を担う
class MessageFormatter
```
#### 3-3-4. データを集める
名詞 + Collector
```python
# Google Analyticsのイベントを収集
class GAEventCollector
```

### 3-4. データソースをラップする
#### 3-4-1. DB、http 通信、キャッシュ等をカプセル化
名詞 + Provider
```python
# タイムラインに関連するデータを提供する
class TimelineProvider
```
#### 3-4-2. データ管理（モデル）
名詞 + Manager
```python
# 設定を管理する
class ConfigurationManager
```
#### 3-4-3. データの読み込み
名詞 + Loader
```python
# ブックマークされたコンテンツを読み込む
class BookmarkedContentLoader
```
#### 3-4-5. ログを出力（またはLogクラスへのアクセスを提供）
Logger
```python
# API利用ログを出力する
class APIUsageLogger
```
#### 3-4-6. 設定を保存
名詞 + Configurator
```python
# アプリケーションの設定を保存する
class ApplicationConfigurator
```
#### 3-4-7. データ構造に変更を加える（バージョンアップなど）
名詞 + Migrator
```python
# JSONデータの構造を変更
class JSONStructureMigrator
```

### 3-5. 非同期処理を扱う
#### 3-5-1. 一連の非同期処理を行う
名詞 + Job/Task
```python
# ファイルやデータのアップロードを行う非同期処理を管理する
class UploadJob
class UploadTask
```
#### 3-5-2. 与えられたJobやTaskを実行
名詞 + Runner
```python
# ファイルやデータのアップロードを行う処理を実行する
class UploadJobRunner
class UploadTaskRunnner
```

## その他気をつけるべき点
#### 不可算名詞をなるべく使わない
単数形・複数形の使い分けるだけで、単体のオブジェクトとリストなど複数のデータが集まったものを区別できるため、なるべく可算名詞を用いる。
```python
# ✕
user_data

# ◯
user_property
user_attribute
```
#### 二重否定を使わない
否定が重なると、True,Falseがわかりにくくなる。否定の形容詞を用いる際には注意。
```python
# ✕
if not disabled:
    ...

# ◯
if enabled:
```
#### クラス名は単数形にする
クラス名に複数形を用いると、集合体になった場合などに変数の名前がわかりにくくなる。
```python
# ✕
class Cotents
# Contentsオブジェクト
contents
# Contentsオブジェクトのリスト
contents_list # contentのリストのリスト?

# ◯
class Cotent
# Contentオブジェクト
content
# Contentオブジェクトのリスト
contents # 複数形にするだけでよい
```
#### データ型を含めてもよい
```python
user_list
query_string
```
#### 否定形の形容詞を用いる
notをつけるだけでは回りくどい命名になることがある。
```python
# ✕
not_allowed

# ◯
denied
```
#### 動詞を複数用いない
```python
# ✕
is_allow
notify_expire

# ◯
is_allowed
notify_expiration
```

## 最後に

:::note inf
弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています！興味をお持ちいただける方は、[こちら](https://www.recruit.nuco.co.jp/?qiita_item_id=94bd9e5d5dfd665ad044)まで。
:::