Open lunemec opened 6 years ago
Can you give an example of services with a distinct responsibility which need too many repositories injected? ImportService seems like a special example with a large surface area which can be solved differently.
@Phr0ztByte hmm, you are correct. There aren't that many. I ran into this issue in out import service, which basically loads data into all our tables. And that is where I'd like to refactor the code to be a bit more readable.
I think you can have the return types of your functions also be interfaces.
type Model interface {
Get(uint) (Row, error)
Save() (error)
}
// Row could be an empty interface if you can't think of
// any useful "methods" on your row values...
type Row interface {}
// and implementations
type User struct {
Name string
Password []byte
}
func (u User) Get(id uint) (Row, error) {
return &User{}, nil
}
func (u User) Save() error {
return nil
}
// so when your code does...
user, err := User{}.Get(5)
fmt.Printf("User name is: %s\n", user.Name)
The Go compiler should see that the Get()
function for your User
struct returns a User
(which satisfies the Row
interface, and is fine), and let you access struct properties like User.Name
(which don't have anything to do with the Row
) because it knows it's a User object. And same with all your other models.
Might need some tweaking but that general idea might work.
@kirsle yes, that might work. I'll try to write a bit using this, to see if there are any problems with this. One downside I can think of is having to have type casts everywhere to discern between tables, which is not ideal.
Currently there is one repository interface for each DB table.
This leads to services having too many arguments #2 . However if there'd be one big interface, it would break the principle that interfaces should have as small surface area as possible. Maybe there should not be any interfaces here at all?