5

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

明らかに、このコードは実行されません。問題が表示されるだけです。私は2番目のアプローチがより好きです。メソッド名は少し一般的かもしれませんが、コンテキスト (クラス名、パラメーター、戻り値の型) を見るとかなり明確です。2 番目のアプローチで発生する可能性がある問題の 1 つは、同じ Type で別の get メソッドが必要な場合にどうなるかということです。たとえば、年齢でユーザーを取得したい場合。助けてくれてありがとう。

クク

4

4 に答える 4

3

選択をはるかに簡単にするために答える必要がある2つの主要な質問があります。

  1. このサービスが複数のエンティティと取引されることは絶対にありませんか?

    言い換えれば、次のUserServiceような追加のメソッドがあるシナリオがありgetRoles()ますか?答えが「はい」の場合は、間違いなくオプションAを使用します。

  2. サービスごとに確実に1つのエンティティを使用する場合は、サービスごとのインターフェイスも必要ですか、それとも一般的な汎用インターフェイスを使用しますか?

    したがって、オプション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();
    }
    

    より具体的な機能を必要とする具体的なサービスは、この汎用サービスを拡張できます。

于 2012-07-29T05:02:17.533 に答える
2

最近の最新の IDE を考えると、私は Tomasz に同意します。これはかなり主観的な質問です。

コードが最終的にどのようになるか (および API の拡張の可能性) を考慮する必要があります。

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

冗長なメソッド名には賛否両論があります。個人的には、最新の IDE の能力を考えると、反対意見は徐々に減っていると思います。

個人的には、例 A の方が好きです。各メソッドが何をしているかの意図がより明確になっています。

于 2012-07-29T04:30:41.340 に答える
1

最初のアプローチはよりきれいに見えます。前もってより多くの情報を提供します。コードを読んだ人は、コードの意味をすぐに理解できます。これは、他の人のコードをデバッグまたは保守する際に重要です。

2 つの最高に設計されたフレームワークから行っていることに近い 2 つの例を次に示します。

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

春:

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

これらのインターフェイスからわかるように、コードを読んでいれば、戻ってオブジェクトの型を確認しなくても、コードが何を行っているかをすぐに知ることができます。

私はあなたの例 A に投票します。

于 2012-07-29T05:18:45.937 に答える
1

あなたの問題は、「冗長になる」と「混乱する」ことです。冗長になると、クライアントはメソッド名を見て機能を推測することでコードを作成します。ただし、メソッドのシグネチャ(および戻り値の型) により、その機能が明確になるため、2 番目のバージョンを好みます。IDE のサポートと適切なコメント/ドキュメントにより、2 番目のバージョンはより簡潔になり、同様に便利になります。

UserService#add(User)willを解釈する方法は他にありませんadding user。他の方法についても同様です。コードは小さく見え、タイピングも少なくなります。

于 2012-07-29T04:47:38.977 に答える