This is a related question and the OP appeared to go with extreme levels of granularity. The answers gave a good overview but I gather it's still somewhat down to personal interpretations/situations as to where to draw the line. I want to know from the examples below which one best represents SRP.
Example 1
Say you have a UserService class with the ff. methods
createUser()updateUser()deleteUser()
The UserService is only "responsible" for all things you can with with the Users. Is this a good or "minimum acceptable" implementation of SRP as it doesn't deal with Products, Shipping etc?
Example 2
Or, do you have to at least be one level granular like the ff. classes/methods:
CreateUserService->createUser()UpdateUserService->updateUser()deleteUserService->deleteUser()
This way CreateUserService is only responsible for creating a user, nothing else. CreateUserService may also contain other supporting methods to properly perform user creation e.g., it can have doesUserAlreadyExist() method to prevent duplicates. This seems to be a better approach.
Example 3
Or, do you still go another level deep and separate the supporting methods too:
CreateUserService->createUser()UserExistService->doesUserAlreadyExist()
This further separates the responsibility of CreateUserService and UserExistService
My hunch tells me example #2 is the way to go but #3 isn't that far fetched. While #1 seems to be the minimum acceptable implementation.
Based on the above examples, which one is the best implementation of SRP? (or maybe there's some other implementation I missed)?