Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean API Design

Which would be the better way to design an API:

Example A:
public class UserService {
  public void addUser(final User user);
  public void addUserToIndex(final User user, final int index);
  public User lookUpUser(final User user);
  public User getUserByIndex(final int index );
  public void removeUser(final User user);
  public List<User> getAllUsers();
}

Example B:
public class UserService {
  public void add(final User user);
  public void add(final User user, final int index);
  public User lookUp(final User user);
  public User get(final int index);
  public void remove(final User user);
  public List<User> getAll();
}

Obviously this code will not run - it should just show the problem. I like the second approach more. The method name might be a little bit generic but the context (className, parameter, return Type) makes it pretty clear. One problem which the second approach might have is, what happens if I would need another get method with the same Type. For example, if I want to get a User by their age. Thanks in advance for any help.

kuku

like image 590
kukudas Avatar asked Jul 28 '12 22:07

kukudas


2 Answers

There are two main questions, which you need to answer to make your choice much easier:

  1. Are you absolutely 100% sure that you will never have this service deal with more than one entity?

    In other words, can there be a scenario where UserService will have additional methods such as getRoles()? If the answer is yes, you're definitely going with option A.

  2. If you're definitely going to have one entity per service, do you even need a per-service interface or would you rather use a common generic one?

    So, instead of your option B you can have something like

    public class Service<T> {
        public void add(final T entity);
        public void add(final T entity, final int index);
        public T lookUp(final T entity);
        public T get(final int index);
        public void remove(final T entity);
        public List<T> getAll();
    }
    

    Concrete services that need more specific functionality can then extend this generic service.

like image 120
ChssPly76 Avatar answered Oct 03 '22 09:10

ChssPly76


Given modern IDEs these days, I agree with Tomasz, that's a rather subjective question.

You have to consider what the code might end up looking like (and possible extenstions to the API).

a.add(b); // :P this would make no sense at all
a.addUser(b) // is at least more descriptive

There is an argument for for and against verbose method names. Personally with the abilities of modern IDEs, I'd say the argument against is slowly losing weight.

Personally, I prefer example A, it's much clearer the intention of what each method is doing

like image 30
MadProgrammer Avatar answered Oct 03 '22 10:10

MadProgrammer