2012-07-28 21 views
5

que sería la mejor manera de diseñar una API:Clean Design 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(); 
} 

Obviamente este código no se ejecutará - que sólo debe mostrar el problema. Me gusta más el segundo enfoque. El nombre del método puede ser un poco genérico, pero el contexto (className, parameter, return Type) lo deja bastante claro. Un problema que podría tener el segundo enfoque es qué pasaría si necesitaría otro método get con el mismo tipo. Por ejemplo, si quiero obtener un usuario por su edad. Gracias de antemano por cualquier ayuda.

kuku

+1

+1 por ejemplo B, pero casi no encuentro esta pregunta como constructiva ya que la respuesta es muy subjetiva –

+0

Supongo que un uso típico sería 'userService.addUser (user)' que hace que la opción A sea bastante redundante. – Xion

+2

En lugar de 'public void add (usuario final User, índice int final);', debe considerar 'public void insert (usuario final User, índice int final);'. Creo que este es el nombre comúnmente utilizado en la API de Java. –

Respuesta

3

Hay dos cuestiones principales, que usted necesita para responder a hacer su elección mucho más fácil:

  1. ¿Estás absolutamente 100% seguro de que usted nunca tendrá este acuerdo de servicio con más de una entidad?

    En otras palabras, ¿puede haber un escenario donde UserService tenga métodos adicionales como getRoles()? Si la respuesta es sí, definitivamente va con la opción A.

  2. Si definitivamente va a tener una entidad por servicio, ¿necesita una interfaz por servicio o prefiere utilizar una genérica común?

    Así, en lugar de la opción B se puede tener algo como servicios

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

    de hormigón que necesitan una funcionalidad más específico, entonces se puede extender este servicio genérico.

2

Dada IDE modernos en estos días, estoy de acuerdo con Tomasz, eso es una pregunta bastante subjetiva.

Tienes que considerar cómo se verá el código (y posibles extensiones de la API).

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

No es un argumento a favor y en contra de los nombres de métodos detallados. Personalmente con las habilidades de los IDEs modernos, diría que el argumento en contra está perdiendo peso lentamente.

Personalmente, prefiero el ejemplo A, es mucho más clara la intención de lo que cada método está haciendo

+0

me molestaría si heredé el código 'a.add (b)', esperaría un poco más creatividad del namer de 'a' y' b'. – akf

+0

Te presentaré al chico entero escribió las bibliotecas centrales para la basura que he heredado. Cada desarrollador nuevo que he introducido al código llora – MadProgrammer

1

su problema es 'cada vez más detallado' vs 'confundirse'. Como obtener verboso hace que el cliente codifique adivinando la funcionalidad mirando el nombre del método . Sin embargo, prefiero la segunda versión, ya que firma de método (y return type) deja en claro lo que hace. Con el soporte de IDE y el comentario/documento adecuado, la segunda versión es más escueta e igualmente útil.

No hay otra forma de interpretar UserService#add(User) hará cualquier cosa que no sea adding user; lo mismo vale para otros métodos. El código parece pequeño y es menos tipado.

1

Primer enfoque parece más limpio. Da más información por adelantado.Las personas que leen el código conocerán instantáneamente el significado del código, que es importante al depurar o mantener el código de otra persona.

Éstos son 2 ejemplos que están cerca de lo que está haciendo desde 2 de los marcos mejor diseñados:

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

primavera:

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

como se puede ver a partir de estas interfaces, si estaba leyendo el código, sería instantáneamente posible decir qué está haciendo el código sin tener que retroceder y mirar el tipo de objeto.

Voto tu Ejemplo A. Simplemente hace la vida de todos más simple.

+0

¿Quiere decir que el ejemplo A es más limpio? – kukudas

+0

oh lo siento ... tienes razón ... editará ..: D –

+0

no hay problema, gracias por tu aportación. sin embargo, si nos fijamos en la API de recopilación de Java, también se llama add() y no addElement o addObject. – kukudas