Uncle Bob Martin の「Clean Architecture」を使用して設計された Go プログラムで、ID の適切なタイプを見つけようとしています。
type UserID ...
type User struct {
ID UserID
Username string
...
}
type UserRepository interface {
FindByID(id UserID) (*User, error)
...
}
私は Uncle Bob Martin の「クリーン アーキテクチャ」に従っています。ここでは、コードが一連のレイヤーとして編成されています (外部から:インフラストラクチャ、インターフェイス、ユースケース、およびドメイン)。原則の 1 つは依存関係の規則です。ソース コードの依存関係は内側のみを指すことができます。
私のUser
タイプはドメイン層の一部であるため、ID
タイプは のために選択されたデータベースに依存することはできませんUserRepository
。MongoDB を使用している場合、ID はObjectId
( string
) である可能性がありますが、PostgreSQL では整数を使用する可能性があります。ドメイン層のUser
型は、実装する型が何であるかを知ることができません。
依存性注入により、実際の型 (例: ) がインターフェイスMongoUserRepository
を実装し、メソッドを提供します。これはインターフェイスまたはインフラストラクチャ層で定義されるため、(より内側の) ドメイン層での定義に依存する可能性があります。UserRepository
FindByID
MongoUserRepository
UserRepository
使用を検討しました
type UserID interface{}
ただし、外側の層のいずれかのコードが誤った実装型を割り当てようとすると、コンパイラはあまり役に立ちません。
データベースが指定されているインターフェイス レイヤーまたはインフラストラクチャ レイヤーで特定のタイプを決定して要求したいのですUserID
が、ドメイン レイヤー コードにその情報をインポートさせることはできません。依存関係の規則に違反するからです。
私も検討しました(そして現在使用しています)
type UserID interface {
String() string
}
ただし、これは、データベースが ID に文字列を使用するという知識を前提としています (私は MongoDB をObjectId
-- の型シノニムで使用していますstring
)。
コンパイラが最大限の型安全性を提供し、依存関係の規則に違反しないようにしながら、慣用的な方法でこの問題を処理するにはどうすればよいですか?