Java 对于这种情况,是单身汉、工厂还是其他更好的选择?

Java 对于这种情况,是单身汉、工厂还是其他更好的选择?,java,api,design-patterns,singleton,Java,Api,Design Patterns,Singleton,我正试图找到最好的OO方法来实现这一点,我将感谢您的帮助 我认为最简单的方法是向您展示我是如何做到的,并尝试在(我简化了它)之后解释我想要什么: 抽象公共类MyServiceApi{ 私有静态MyServiceApi实例=null; 公共静态getInstance(类cls){ if(实例==null){ 试一试{ instance=cls.newInstance(); } catch(实例化异常e){} 捕获(非法访问例外){} } 返回(T)实例; } 私有HashMap头; 受保护的MyS

我正试图找到最好的OO方法来实现这一点,我将感谢您的帮助

我认为最简单的方法是向您展示我是如何做到的,并尝试在(我简化了它)之后解释我想要什么:

抽象公共类MyServiceApi{
私有静态MyServiceApi实例=null;
公共静态getInstance(类cls){
if(实例==null){
试一试{
instance=cls.newInstance();
}
catch(实例化异常e){}
捕获(非法访问例外){}
}
返回(T)实例;
}
私有HashMap头;
受保护的MyServiceApi(){}
公共HashMap getHeaders(){
返回标题;
}
公共void setHeaders(HashMap头){
this.headers=标题;
}
受保护的T发送(字符串url、IMYServiceAPI请求、类到){
//做些事情
//要点:还要为请求设置标题
}
受保护的字符串getBaseUrl(){
返回“http://api.mywebsite.com/";
}
}
公共类UsersApi扩展了MyServiceApi{
公共静态用户SAPI getInstance(){
返回getInstance(UsersApi.class);
}
受保护的UsersApi(){
超级();
}
@凌驾
受保护的字符串getBaseUrl(){
返回super().getBaseUrl()+“Users/”;
}
//mutliple函数,该函数调用API中的特定URL,并基于调用返回specifics对象,例如:
公共MyServiceAppUsersResponse getUsers(MyServiceAppUsersRequest请求){
返回send(getBaseUrl()+“get”,request,MyServiceApiUsersResponse.class);
}
}
公共类ItemsApi扩展了MyServiceApi{
公共静态项SAPI getInstance(){
返回getInstance(ItemsApi.class);
}
受保护项目SAPI(){
超级();
}
@凌驾
受保护的字符串getBaseUrl(){
返回super().getBaseUrl()+“Items/”;
}
//mutliple函数,该函数调用API中的特定URL,并根据调用返回specifics对象,例如:
公共MyServiceAppItemsResponse getUsers(MyServiceAppItemsRequest请求){
返回send(getBaseUrl()+“get”,request,myServiceAppItemsResponse.class);
}
}
既然你有了这个想法,我就有点迷糊了

首先,我不知道我所做的是否正确(以JavaOO的方式)。我认为这还不错,但我确实缺乏经验

其次,一旦我的项目运行,
MyServiceApi
将保留相同的头,我不会调用其他API或使用其他凭据。这就是我考虑单例的原因:我在应用程序开始时设置头,然后我只需要执行请求。 但是我相信拥有
UsersApi
ItemsApi
扩展
myservicecapi
是最好的方法。他们使用MyServiceApi,但不扩展其功能。 另外,我听说单例是反模式的,不利于测试等

所以现在我很放松,我不知道该怎么办。你会怎么做

一个可能的想法是删除
myservicecapi
的摘要,并在其上设置一个单例,让
UsersApi
ItemsApi
使用
myservicecapi
,但不是通过扩展它,而是如何管理getBaseUrl呢


非常感谢你的帮助,我真的很感激

使用依赖注入而不是单例

看起来您正在尝试使用一个具有基本URL并设置标题的服务

使用依赖项注入,创建一个名为MyApiService的服务,就像您拥有并让UsersApi和ItemsApi依赖于它一样,如下所示:

public class MyServiceApi {

    private final String baseUrl;
    private final HashMap<String, String> headers;

    protected MyServiceApi(String baseUrl, HashMap<String, String> headers) {
        this.baseUrl = baseUrl;
        this.headers = headers;
    }

    protected <T extends IMyServiceApiResponse> T send(String url,
            IMyServiceApiRequest request, Class<T> to) {
        // Do some stuffs

        // IMPORTANT : Also set headers to the request
    }

    protected String getBaseUrl() {
        return baseUrl;
    }
}

public class UsersApi {

    private final MyServiceApi myServiceApi;

    protected UsersApi(MyServiceApi myServiceApi) {
        this.myServiceApi = myServiceApi;
    }

    protected String getBaseUrl() {
        return myServiceApi.getBaseUrl() + "Users/";
    }

    // mutliple function that calls a specific URL in the API, and return
    // specifics object based on the call, for example :
    public MyServiceApiUsersResponse getUsers(
            MyServiceApiUsersRequest request) {
        return myServiceApi.send(getBaseUrl() + "get", request,
                MyServiceApiUsersResponse.class);
    }
}
公共类MyServiceApi{
私有最终字符串baseUrl;
私有最终HashMap头;
受保护的MyServiceApi(字符串baseUrl、HashMap头){
this.baseUrl=baseUrl;
this.headers=标题;
}
受保护的T发送(字符串url,
IMYServiceAPI请求,类到){
//做些事情
//要点:还要为请求设置标题
}
受保护的字符串getBaseUrl(){
返回baseUrl;
}
}
公共类UsersApi{
私有最终MyServiceApi MyServiceApi;
受保护的用户SAPI(MyServiceApi MyServiceApi){
this.myServiceApi=myServiceApi;
}
受保护的字符串getBaseUrl(){
返回myServiceApi.getBaseUrl()+“Users/”;
}
//调用API中特定URL的mutliple函数,并返回
//基于调用指定对象,例如:
公共MyServiceApiUsers响应getUsers(
MyServiceApiUsersRequest请求){
返回myServiceApi.send(getBaseUrl()+“get”,请求,
MyServiceApiUsersResponse.class);
}
}
您还可以做一些其他事情:

  • 如果希望一致地公开getBaseUrl,请创建一个由MyServiceApi和UsersApi实现的接口
  • 看一看关于那里的一些信息

    • 我会这样写

      enum MyServiceApi {
          UsersApi {
              public MyServiceApiUsersResponse getUsers(MyServiceApiUsersRequest request) {
                  return send(getBaseUrl() + "Users/get", request, MyServiceApiUsersResponse.class);
              }
      
          },  ItemsApi {
              // mutliple function that calls a speicfic URL in the API, and return specifics object based on the call, for example :
              public MyServiceApiItemsResponse getUsers(MyServiceApiItemsRequest request) {
                  return send(getBaseUrl() + "Items/get", request, MyServiceApiItemsResponse.class);
              }
          };
      
          private final Map<String, String> headers = new LinkedHashMap<String, String>();
      
          public Map<String, String> getHeaders() {
              return headers;
          }
      
          public void setHeaders(HashMap<String, String> headers) {
              this.headers.clear();
              this.headers.putAll(headers);
          }
      
          public abstract <T extends IMyServiceApiResponse> T send(String url, IMyServiceApiRequest request, Class<T> to);
      
          protected String getBaseUrl() {
              return "http://api.mywebsite.com/";
          }
      }
      
      enum MyServiceApi{
      UsersApi{
      公共MyServiceAppUsersResponse getUsers(MyServiceAppUsersRequest请求){
      返回send(getBaseUrl()+“Users/get”、request、MyServiceApiUsersResponse.class);
      }
      },ItemsApi{
      //mutliple函数,该函数调用API中的特定URL,并根据调用返回specifics对象,例如:
      公共MyServiceAppItemsResponse getUsers(MyServiceAppItemsRequest请求){
      返回send(getBaseUrl()+“Items/get”、request、MyServiceApiItemsResponse.class);
      }
      };
      私有最终映射头=新LinkedHashMap();
      公共映射getHeaders(){
      返回标题;
      }
      公共void setHeaders(HashMap头){
      this.headers.clear();
      this.headers.putAll(headers);
      }
      公共摘要不能发送(字符串)
      
      enum MyServiceApi {
          UsersApi {
              public MyServiceApiUsersResponse getUsers(MyServiceApiUsersRequest request) {
                  return send(getBaseUrl() + "Users/get", request, MyServiceApiUsersResponse.class);
              }
      
          },  ItemsApi {
              // mutliple function that calls a speicfic URL in the API, and return specifics object based on the call, for example :
              public MyServiceApiItemsResponse getUsers(MyServiceApiItemsRequest request) {
                  return send(getBaseUrl() + "Items/get", request, MyServiceApiItemsResponse.class);
              }
          };
      
          private final Map<String, String> headers = new LinkedHashMap<String, String>();
      
          public Map<String, String> getHeaders() {
              return headers;
          }
      
          public void setHeaders(HashMap<String, String> headers) {
              this.headers.clear();
              this.headers.putAll(headers);
          }
      
          public abstract <T extends IMyServiceApiResponse> T send(String url, IMyServiceApiRequest request, Class<T> to);
      
          protected String getBaseUrl() {
              return "http://api.mywebsite.com/";
          }
      }