通用接口

use*_*585 54 java interface

假设我想定义一个代表远程服务调用的接口.现在,对远程服务的调用通常会返回一些内容,但也可能包含输入参数.假设实现类通常只实现一种服务方法.鉴于以上信息,以下是一个糟糕的设计(它感觉不太正确):

public interface IExecutesService<A,B>
{
    public A executeService();
    public A executeService(B inputParameter);
}
Run Code Online (Sandbox Code Playgroud)

现在,假设我使用一个使用输入参数执行远程服务的类来实现此接口:

public class ServiceA implements IExecutesService<String,String>
{
  public String executeService()
  {
    //This service call should not be executed by this class
    throw new IllegalStateException("This method should not be called for this class...blabla");
  }

  public String executeService(String inputParameter)
  {
    //execute some service
  }
Run Code Online (Sandbox Code Playgroud)

关于上述问题我有两个问题:

  1. IExecutesService<A,B>在您想要提供需要不同输入参数和接口方法的返回类型的子类的情况下,是否使用通用接口()?
  2. 我怎样才能做到更好?即我想在一个公共接口(IExecutesService)下将我的服务执行者分组; 但是,实现类通常只实现其中一个方法,并且使用IllegalStateException感觉非常难看.此外,对于在IExecutesService<A,B>没有任何输入参数的情况下调用服务的实现类,B类型参数将是多余的.对于两个不同的服务调用来说,创建两个独立的接口似乎也是过度的.

cle*_*tus 84

这是一个建议:

public interface Service<T,U> {
    T executeService(U... args);
}

public class MyService implements Service<String, Integer> {
    @Override
    public String executeService(Integer... args) {
        // do stuff
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

由于类型擦除,任何类只能实现其中之一.这至少消除了冗余方法.

这不是你提出的不合理的界面,但我不是百分之百确定它增加了什么价值.您可能只想使用标准Callable接口.它不支持参数,但接口的那部分值最小(imho).

  • 使用"I"前缀接口是一种真正的.Net'主义.它并不真正属于Java代码. (14认同)
  • 在.NET之前,匈牙利符号用于在苏黎世为Eclipse(及其祖先,VAME ......)开发的代码中,因此使用I来为Eclipse中的接口名称添加前缀. (4认同)
  • 具有讽刺意味的是,使用"I"来为接口名称添加前缀并不是真正的[匈牙利表示法](https://msdn.microsoft.com/en-us/library/aa260976(v = vs.60).aspx).该符号旨在促进有关预期用途的有用信息.例如,"csPassword"可能表示"加密安全密码",而"rLast"可能表示"最后一行".添加"I"前缀不提供有关如何使用接口的信息,因此是多余的. (3认同)

dfa*_*dfa 20

这是另一个建议:

public interface Service<T> {
   T execute();
}
Run Code Online (Sandbox Code Playgroud)

使用这个简单的接口,您可以通过具体服务类中的构造函数传递参数:

public class FooService implements Service<String> {

    private final String input1;
    private final int input2;

    public FooService(String input1, int input2) {
       this.input1 = input1;
       this.input2 = input2;
    }

    @Override
    public String execute() {
        return String.format("'%s%d'", input1, input2);
    }
}
Run Code Online (Sandbox Code Playgroud)


den*_*nov 9

我会留下两个不同的界面.

你说'我想把我的服务执行者分组在一个公共接口下......对于两个不同的服务调用来说,创建两个独立的接口似乎有些过分......一个类只会实现其中一个接口'

目前尚不清楚具有单一界面的原因是什么.如果要将其用作标记,则可以改为使用注释.

另一点是,可能的情况是您的需求发生变化,并且在界面上出现带有其他签名的方法.当然可以使用Adapter模式,但是看到特定的类实现与三个方法的接口会很奇怪,其中两个方法都会抛出UnsupportedOperationException.第四种方法可能出现等.