Clean API Design

What would be the best way to develop 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 work - it should just show the problem. I like the second approach more. The method name may be a little generic, but the context (className, parameter, return Type) makes it pretty straightforward. One of the problems that the second approach may have is what happens if I 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.

Cook

+5
source share
4 answers

There are two basic questions that you need to answer to make your choice a lot easier:

  • Are you absolutely 100% sure that you will never have this service with multiple facilities?

    , , UserService , getRoles()? "", A.

  • , ?

    , B -

    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();
    }
    

    , , .

+3

IDE , , .

, (, , extenstions API).

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

. IDE, , .

A, ,

+2

, " ", "". verbose , , . , , ( ) , . IDE /, .

UserService#add(User) -, adding user; . .

+1
source

The first approach seems cleaner. Provides additional information. People reading the code will immediately recognize the meaning of the code, which is important when debugging or maintaining another user's code.

Here are two examples that are close to what you are doing from 2 of the best developed frameworks:

Jdk7

package java.security.acl

public interface Group extends Principal
{

   public boolean addMember(Principal user);
   public boolean removeMember(Principal user);
   public boolean isMember(Principal member);
   public Enumeration<? extends Principal> members();
}

Spring:

public interface GroupManager {

   List<String> findAllGroups();
   List<String> findUsersInGroup(String groupName);
   void createGroup(String groupName, List<GrantedAuthority> authorities);
   void deleteGroup(String groupName);
   void renameGroup(String oldName, String newName);
   void addUserToGroup(String username, String group);
   void removeUserFromGroup(String username, String groupName);
   List<GrantedAuthority> findGroupAuthorities(String groupName);
   void addGroupAuthority(String groupName, GrantedAuthority authority);
   void removeGroupAuthority(String groupName, GrantedAuthority authority);
}

As you can see from these interfaces, if I were reading the code, you could immediately say what the code does, without returning and without looking at the type of object.

I will vote for your example A. It just makes everyone live easier.

+1
source

All Articles