Ich versuche, einen passenden Typ für meine IDs in einem Go-Programm zu finden, das mit Uncle Bob Martins "Clean Architecture" entworfen wurde.Generischer ID-Typ für "Saubere Architektur" Go-Programm
type UserID ...
type User struct {
ID UserID
Username string
...
}
type UserRepository interface {
FindByID(id UserID) (*User, error)
...
}
Ich folge Onkel Bob Martins "Clean Architecture", wo der Code als eine Reihe von Schichten organisiert ist (von außen nach innen: Infrastruktur, Schnittstellen, usecases und Domain) . Eines der Prinzipien ist die Abhängigkeitsregel: Quellcodeabhängigkeiten können nur nach innen zeigen.
Mein User
Typ ist Teil des Domänen-Layers und daher kann der Typ ID
nicht von der Datenbank abhängen, die für die UserRepository
ausgewählt wurde; Wenn ich MongoDB verwende, könnte die ID eine ObjectId
(string
) sein, während ich in PostgreSQL eine ganze Zahl verwenden könnte. Der User
Typ in der Domänenebene kann nicht wissen, was der Implementierungstyp sein wird.
Durch die Abhängigkeitsinjektion wird ein realer Typ (z. B. MongoUserRepository
) die Schnittstelle UserRepository
implementieren und die FindByID
-Methode bereitstellen. Da diese MongoUserRepository
in den Schnittstellen oder der Infrastrukturschicht definiert wird, kann sie von der Definition von UserRepository
in der (mehr nach innen gerichteten) Domänenschicht abhängen.
Ich betrachtete
type UserID interface{}
verwenden, aber dann wird der Compiler nicht sehr hilfreich sein, wenn Code in einen der äußeren Schicht versucht, in einem falschen Implementierung Typ zuordnen.
Ich möchte die Schnittstelle Layer oder Infrastruktur-Layer, wo die Datenbank angegeben ist, bestimmen und erfordern den spezifischen Typ für UserID
, aber ich kann nicht den Domänen-Layer-Code importieren diese Informationen, weil das die Abhängigkeitsregel verletzt.
ich auch in Betracht gezogen (und bin derzeit)
type UserID interface {
String() string
}
aber das setzt die Kenntnis, dass die Datenbank-Strings für seine IDs verwenden (ich bin mit MongoDB mit seinem ObjectId
- eine Art Synonym für string
).
Wie kann ich dieses Problem idiomatisch behandeln, während der Compiler maximale Typsicherheit bietet und die Abhängigkeitsregel nicht verletzt?
Das könnte funktionieren. Ich werde darüber nachdenken.(Das ist eine Art von Ort, an dem ich mit meiner '' 'Type UserID Schnittstelle voranging. { String() String }' ''). – Ralph
Ich glaube nicht, dass dies Kompilierzeit Typprüfung bietet. Ein 'PgUserRepository'-Typ 'FindByID'-Methode kann auch eine Zeichenkette' MongoUserID' akzeptieren. Oder jeder Typ, der die 'UesrID'-Schnittstelle implementiert. – abhink
@abhink, wenn Sie Pg-spezifische Methode haben, warum würden Sie Schnittstelle anstelle von Strukturtyp als Argumenttyp in der FindByID-Methode verwenden? – Nebril