2025/11/16
Contents Each class (struct + methods) should work independently.
(各クラス(構造体+メソッド)は独立して動作するようにする)
解説 クラスが他のクラスやグローバル状態に暗黙的に依存していると、テストが困難になり、再利用性が低下します。各クラスは、必要な依存関係を明示的に受け取り、独立して動作すべきです。これにより、単体テストでモックやスタブを容易に注入でき、クラスの振る舞いを分離して検証できます。独立性の高いクラスは、異なるコンテキストでの再利用も容易です。
具体例 // 悪い例(グローバル状態に依存)
var globalDB * Database // グローバル変数
type UserService struct {}
func (s * UserService ) GetUser (id string ) (User , error ) {
return globalDB .Query (id ) // 暗黙的な依存
}
// 良い例(依存関係を明示的に注入)
type UserService struct {
db Database
}
func NewUserService (db Database ) * UserService {
return & UserService {db : db }
}
func (s * UserService ) GetUser (id string ) (User , error ) {
return s .db .Query (id ) // 明示的な依存
}
// テストでのモック使用
type MockDatabase struct {}
func (m * MockDatabase ) Query (id string ) (User , error ) {
return User {ID : id , Name : "Test User" }, nil
}
func TestGetUser (t * testing .T ) {
mockDB := & MockDatabase {}
service := NewUserService (mockDB )
user , err := service .GetUser ("123" )
if err != nil {
t .Fatal (err )
}
if user .Name != "Test User" {
t .Errorf ("unexpected user name: %s" , user .Name )
}
}
参考リンク core
coding-standard
2025/11/16
Contents Use full words rather than abbreviations (e.g., compensatingTransaction instead of ct). Commonly accepted abbreviations like db are fine.
(略語ではなく完全な単語を使う(例:ctではなくcompensatingTransaction)。dbのように一般的に受け入れられている略語は問題ない)
解説 略語は、書いた本人以外には意味が不明確で、コードの理解を妨げます。完全な単語を使用することで、コードの意図が明確になり、新しいメンバーでも容易に理解できます。現代のエディタには自動補完機能があるため、長い名前でも入力の手間は問題になりません。ただし、広く認知されている略語(例:db、api、html、url)は使用しても問題ありません。
具体例 // 悪い例(独自の略語を使用)
func ProcUsrData (usr * Usr ) error {
// usr, Procは何の略か不明
res := CalcTtl (usr .Itms )
// res, Ttl, Itmsは何の略か不明
if err := SaveToDb (res ); err != nil {
return err
}
return nil
}
type Usr struct {
Nm string // Nmは何の略?
Em string // Emは何の略?
Ph string // Phは何の略?
Itms []Item
}
func CalcTtl (itms []Item ) float64 {
ttl := 0.0
for _ , itm := range itms {
ttl += itm .Prc
}
return ttl
}
// 良い例(完全な単語を使用)
func ProcessUserData (user * User ) error {
total := CalculateTotal (user .Items )
if err := SaveToDatabase (total ); err != nil {
return err
}
return nil
}
type User struct {
Name string
Email string
Phone string
Items []Item
}
func CalculateTotal (items []Item ) float64 {
total := 0.0
for _ , item := range items {
total += item .Price
}
return total
}
// 一般的な略語は使用可(良い例)
type UserRepository struct {
db * sql .DB // dbは一般的
api APIClient // apiは一般的
}
func FetchFromAPI (url string ) ([]byte , error ) {
// url, apiは一般的
resp , err := http .Get (url )
if err != nil {
return nil , err
}
defer resp .Body .Close ()
return io .ReadAll (resp .Body )
}
func GenerateHTML (data TemplateData ) string {
// htmlは一般的
return renderTemplate (data )
}
参考リンク core
coding-standard
2025/11/16
Contents Access struct fields through getter methods; avoid setters.
(構造体のフィールドへのアクセスはゲッターメソッドを通して行い、セッターは避ける)
解説 セッターメソッドを提供すると、オブジェクトの状態がいつでも変更可能になり、不変性が損なわれます。ゲッターのみを提供することで、オブジェクトの読み取り専用アクセスを実現し、予期しない状態変更を防げます。状態の変更が必要な場合は、ビジネスロジックを含むドメインメソッドとして実装すべきです。これにより、状態変更に対する制御が強化され、バグの混入を防ぎます。
具体例 // 悪い例(セッターが存在)
type Account struct {
balance float64
}
func (a * Account ) GetBalance () float64 {
return a .balance
}
func (a * Account ) SetBalance (amount float64 ) {
a .balance = amount // 検証なしで変更可能
}
func main () {
acc := & Account {balance : 1000 }
acc .SetBalance (- 500 ) // 不正な状態を作成可能
}
// 良い例(ゲッターのみ、状態変更はドメインメソッド)
type Account struct {
balance float64
}
func NewAccount (initialBalance float64 ) (* Account , error ) {
if initialBalance < 0 {
return nil , errors .New ("initial balance must be positive" )
}
return & Account {balance : initialBalance }, nil
}
func (a * Account ) Balance () float64 {
return a .balance
}
func (a * Account ) Deposit (amount float64 ) error {
if amount <= 0 {
return errors .New ("deposit amount must be positive" )
}
a .balance += amount
return nil
}
func (a * Account ) Withdraw (amount float64 ) error {
if amount <= 0 {
return errors .New ("withdraw amount must be positive" )
}
if a .balance < amount {
return errors .New ("insufficient balance" )
}
a .balance -= amount
return nil
}
参考リンク core
coding-standard
2025/11/16
Contents Write a one-line comment summarizing the purpose of each function. Argument explanations are unnecessary except in special cases.
(各関数の目的を要約する1行コメントを書く。引数の説明は特別な場合を除いて不要)
解説 関数の目的を簡潔に説明するコメントは、コードの理解を助ける重要な要素です。1行のコメントで「何をする関数か」を明確にすることで、コードレビューや保守作業が効率化されます。ただし、引数や戻り値の詳細な説明は、型や名前から自明な場合は不要です。コメントは実装の詳細ではなく、関数の意図や目的を伝えることに焦点を当てるべきです。
具体例 // 悪い例(コメントなし、または冗長)
func ProcessOrder (order Order ) error {
// この関数はOrderを受け取り、それを処理し、エラーがあればエラーを返します
// 引数: order - 処理するOrder型の変数
// 戻り値: error - エラーがあればerror、なければnil
// ...
}
// 良い例
// ProcessOrder は注文を検証して保存し、確認メールを送信する
func ProcessOrder (order Order ) error {
// ...
}
// CalculateTax は商品価格に対する消費税額を計算する
func CalculateTax (price float64 ) float64 {
return price * 0.1
}
// FetchActiveUsers はアクティブなユーザー一覧をデータベースから取得する
func FetchActiveUsers () ([]User , error ) {
// ...
}
// GenerateInvoicePDF は注文データからPDF形式の請求書を生成する
// pdfOptions: マージン、フォントサイズなど細かい制御が必要な場合のみコメント
func GenerateInvoicePDF (order Order , pdfOptions PDFOptions ) ([]byte , error ) {
// ...
}
参考リンク core
coding-standard
2025/11/16
Contents For dependency injection, depend on interfaces, not concrete implementations.
(依存性注入では、具体的な実装ではなくインターフェースに依存する)
解説 依存性注入において、具体的な実装ではなくインターフェースに依存することで、疎結合な設計が実現されます。インターフェースに依存することで、実装の差し替えが容易になり、テスト時にモックやスタブを注入できます。この原則は依存性逆転の原則(DIP)の実践であり、変更に強く拡張しやすいコードベースを構築するための基盤となります。
具体例 // 悪い例(具体的な実装に依存)
type MySQLDatabase struct {}
func (db * MySQLDatabase ) Query (sql string ) []Row {
// MySQL固有の実装
return nil
}
type UserService struct {
db * MySQLDatabase // 具体的な実装に依存
}
// 良い例(インターフェースに依存)
type Database interface {
Query (sql string ) []Row
}
type MySQLDatabase struct {}
func (db * MySQLDatabase ) Query (sql string ) []Row {
return nil
}
type UserService struct {
db Database // インターフェースに依存
}
func NewUserService (db Database ) * UserService {
return & UserService {db : db }
}
参考リンク core
coding-standard
2025/11/16
Contents Keep domain responsibilities out of utility packages.
(ドメインの責務をユーティリティパッケージに入れない)
解説 ユーティリティパッケージは、文字列操作や日付計算など、ドメイン非依存の汎用的な機能を提供すべきです。ドメイン固有のビジネスロジックをユーティリティに配置すると、ドメイン層の概念が分散し、ビジネスロジックの理解が困難になります。ドメインロジックは、適切なエンティティやドメインサービスに配置することで、コードの意図が明確になり、保守性が向上します。
具体例 // 悪い例(ドメインロジックがutilに配置)
package util
func CalculateOrderTotal (items []Item ) float64 {
total := 0.0
for _ , item := range items {
total += item .Price * float64(item .Quantity )
}
// 1万円以上で送料無料(ドメインルール)
if total < 10000 {
total += 500 // 送料
}
return total
}
// 良い例(ドメインロジックはドメイン層に配置)
package domain
type Order struct {
items []Item
}
func (o * Order ) CalculateTotal () float64 {
subtotal := 0.0
for _ , item := range o .items {
subtotal += item .Price * float64(item .Quantity )
}
shippingFee := o .calculateShippingFee (subtotal )
return subtotal + shippingFee
}
func (o * Order ) calculateShippingFee (subtotal float64 ) float64 {
const freeShippingThreshold = 10000
const standardShippingFee = 500
if subtotal >= freeShippingThreshold {
return 0
}
return standardShippingFee
}
// utilパッケージは汎用機能のみ
package util
func FormatCurrency (amount float64 ) string {
return fmt .Sprintf ("¥%.0f" , amount )
}
参考リンク core
coding-standard
2025/11/16
Contents A class must: 1. Explicitly receive all dependencies (via DI) — it should not secretly rely on any helper. 2. Maintain a consistent responsibility.
(クラスは次を満たす必要がある:1. すべての依存関係を明示的に受け取る(DI経由)— ヘルパーに密かに依存してはいけない。2. 一貫した責任を維持する)
解説 依存関係が暗黙的だと、テストやデバッグが困難になり、コードの理解に時間がかかります。すべての依存関係をコンストラクタで明示的に注入することで、クラスが必要とするものが一目でわかり、モックやスタブを使ったテストが容易になります。また、一貫した責任を維持することで、クラスの目的が明確になり、変更の影響範囲が限定されます。これは保守性の高いコード設計の基本原則です。
具体例 // 悪い例(暗黙的な依存)
type OrderService struct {
// 依存関係が明示されていない
}
func (s * OrderService ) CreateOrder (items []Item ) error {
// 内部でグローバルなhelperを使用
db := GetGlobalDB () // 暗黙的な依存
logger := GetGlobalLogger () // 暗黙的な依存
total := calculateTotal (items )
if err := db .Insert (total ); err != nil {
logger .Error (err )
return err
}
return nil
}
// 良い例(明示的な依存注入)
type OrderService struct {
db Database
logger Logger
pricer PriceCalculator
}
func NewOrderService (db Database , logger Logger , pricer PriceCalculator ) * OrderService {
return & OrderService {
db : db ,
logger : logger ,
pricer : pricer ,
}
}
func (s * OrderService ) CreateOrder (items []Item ) error {
total := s .pricer .CalculateTotal (items )
if err := s .db .Insert (total ); err != nil {
s .logger .Error (err )
return err
}
return nil
}
参考リンク core
coding-standard
2025/11/16
Contents When an Entity requires domain-specific validation, perform it inside the Entity’s own methods.
(エンティティがドメイン固有の検証を必要とする場合、エンティティ自身のメソッド内で実行する)
解説 ドメイン層のエンティティは、自身のビジネスルールを理解し、検証する責任を持つべきです。検証ロジックをエンティティ外部に配置すると、ビジネスルールが分散し、変更時の整合性維持が困難になります。エンティティ内部にドメイン検証を配置することで、ビジネスロジックがカプセル化され、ルールの変更が局所化されます。これは、ドメイン駆動設計における重要な原則です。
具体例 // 悪い例(検証がエンティティ外部)
type Order struct {
Amount float64
Status string
}
func ValidateOrder (order Order ) error {
if order .Amount < 0 {
return errors .New ("amount must be positive" )
}
if order .Status != "pending" && order .Status != "completed" {
return errors .New ("invalid status" )
}
return nil
}
// 良い例(検証がエンティティ内部)
type Order struct {
amount float64
status string
}
func NewOrder (amount float64 ) (* Order , error ) {
o := & Order {amount : amount , status : "pending" }
if err := o .validate (); err != nil {
return nil , err
}
return o , nil
}
func (o * Order ) validate () error {
if o .amount < 0 {
return errors .New ("amount must be positive" )
}
return nil
}
func (o * Order ) Complete () error {
if o .status != "pending" {
return errors .New ("only pending orders can be completed" )
}
o .status = "completed"
return nil
}
参考リンク core
coding-standard
2025/11/16
ルール Infrastructure is built and operated using Terraform
(インフラストラクチャはTerraformを使用して構築および運用する)
解説 このプロジェクトでは、インフラをIaCツールのTerraformで管理します。
コードでインフラを管理することは、生成AIによるインフラ構築を容易にするばかりか、GitとGithubを使ったトレーサビリティの確保の道も開きます。
今や手作業だけでAWSの管理をすることは想像もし難いことです。
サンプルコード 参考リンク Infrastructure
開発ガイドライン
Project Information
2025/11/16
ルール AWS is used as the cloud platform
(クラウドプラットフォームとしてAWSを使用する)
解説 このプロジェクトでは、AWSを標準のクラウドプラットフォームとして採用しています。
AWSは手厚いサポートと情報提供、優秀なサービスラインナップ、安定したエコシステムを持ち、多くの企業での採用実績があります。
サンプルコード 参考リンク Infrastructure
開発ガイドライン
Project Information