对于这种情况,单例、工厂还是其他更好?
我正在尝试找到最好的面向对象方法来做到这一点,我将感谢您的帮助。
我认为最简单的方法是向您展示我是如何做到的,并尝试解释我想要什么(我简化了它):
abstract public class MyServiceApi {
private static MyServiceApi instance = null;
public static <T extends MyServiceApi> T getInstance(Class<T> cls) {
if (instance == null) {
try {
instance = cls.newInstance();
}
catch (InstantiationException e) {}
catch (IllegalAccessException e) {}
}
return (T) instance;
}
private private HashMap<String, String> headers;
protected MyServiceApi() {}
public HashMap<String, String> getHeaders() {
return headers;
}
public void setHeaders(HashMap<String, String> headers) {
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 "http://api.mywebsite.com/";
}
}
public class UsersApi extends MyServiceApi {
public static UsersApi getInstance() {
return getInstance(UsersApi.class);
}
protected UsersApi() {
super();
}
@Override
protected String getBaseUrl() {
return super().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 send(getBaseUrl() + "get", request, MyServiceApiUsersResponse.class);
}
}
public class ItemsApi extends MyServiceApi {
public static ItemsApi getInstance() {
return getInstance(ItemsApi.class);
}
protected ItemsApi() {
super();
}
@Override
protected String getBaseUrl() {
return super().getBaseUrl() + "Items/";
}
// 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() + "get", request, MyServiceApiItemsResponse.class);
}
}
既然您有了想法,我就被困住了。
首先,我不知道我所做的是否正确(以Java OO的方式)。我认为这还不错,但我缺乏经验来确定。
其次,一旦我的项目运行,MyServiceApi
将保留相同的标头,我不会调用其他 API 或使用其他凭据。这就是我考虑 Singleton 的原因:我在应用程序启动时设置标头,然后我只需执行请求即可。 但我相信让 UsersApi
和 ItemsApi
扩展 MyServiceApi
是最好的方法。他们使用 MyServiceApi,但不扩展其功能。 另外,我听说 SingleTon 是反模式的,不利于测试等等。
所以现在我很松散,我不知道该怎么办。你会怎么做?
一个可能的想法是删除 MyServiceApi
的抽象并在其上设置单例,让 UsersApi
和 ItemsApi
使用 MyServiceApi
code> 但不是通过扩展它,但是我将如何管理 getBaseUrl 呢?
真的非常感谢您的帮助,我真的很感激!
I'm trying to find the best OO way to do this, and I would appreciate your help on it.
I think the simplest way is to show you how I've done it and try to explain what I want after (I simplified it) :
abstract public class MyServiceApi {
private static MyServiceApi instance = null;
public static <T extends MyServiceApi> T getInstance(Class<T> cls) {
if (instance == null) {
try {
instance = cls.newInstance();
}
catch (InstantiationException e) {}
catch (IllegalAccessException e) {}
}
return (T) instance;
}
private private HashMap<String, String> headers;
protected MyServiceApi() {}
public HashMap<String, String> getHeaders() {
return headers;
}
public void setHeaders(HashMap<String, String> headers) {
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 "http://api.mywebsite.com/";
}
}
public class UsersApi extends MyServiceApi {
public static UsersApi getInstance() {
return getInstance(UsersApi.class);
}
protected UsersApi() {
super();
}
@Override
protected String getBaseUrl() {
return super().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 send(getBaseUrl() + "get", request, MyServiceApiUsersResponse.class);
}
}
public class ItemsApi extends MyServiceApi {
public static ItemsApi getInstance() {
return getInstance(ItemsApi.class);
}
protected ItemsApi() {
super();
}
@Override
protected String getBaseUrl() {
return super().getBaseUrl() + "Items/";
}
// 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() + "get", request, MyServiceApiItemsResponse.class);
}
}
Now that you have the idea, I'm stuck for something.
First of all, I don't know if what I did is correct (in a Java OO way). I think it's not bad, but I lack the experience to be sure.
Second of all, once my project is running, MyServiceApi
will keep the same headers, I won't call other API or with other credentials. That's why I thought about the Singleton : I set the headers at my application start, and then I just have to do the request.
But I believe having UsersApi
and ItemsApi
extending MyServiceApi
is the best way to do. They use MyServiceApi
, they don't extends its capabilities.
Also, I eard that SingleTon are anti-pattern, bad for tests, etc.
So now I'm loose and I don't know what to do. How would you do that?
A possible idea is to remove the abstract of MyServiceApi
and set a Singleton on it, having UsersApi
and ItemsApi
to use MyServiceApi
but not by extending it, but how would I manage the getBaseUrl then ?
Thank you really much for your help, I really appreciate!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用依赖注入而不是单例。
看起来您正在尝试拥有一个具有基本 URL 并设置标头的服务。
使用依赖注入,创建一个名为 MyApiService 的服务,就像您拥有的服务一样,UsersApi 和 ItemsApi 依赖于它,如下所示:
您可以做的其他一些事情:
Use Dependency Injection rather than a Singleton.
It looks like you're trying to have a single service that has a base URL and sets up your headers.
Using Dependency Injection, create a service called MyApiService, much like you have and have UsersApi and ItemsApi depend on it as in:
A few other things you could do:
这就是我要写的方式
This is how I would write it
这只是为了你的意识。如果您使用单例模式,您的 getInstance 方法应该同步。考虑一个有多个线程正在运行的场景。例如,如果一个线程检查实例是否为空,并且由于它为空,它将进入 try 块。假设它停止,第二个线程进入运行状态。实例仍然为空,并且它也有机会进入 try 块。那么最终你将得到两个实例,并且你的单例策略将被破坏
This is just for your awareness. If you are using Singleton pattern your getInstance method should be synchronized. Think a scenario where you have multiple threads running.For an example if one thread checked the instance is null and since it is null it will go inside the try block.Lets say it halts and the second thread comes to running state. And still the instance is null and it also have the opportunity to go inside the try block. then ultimately you will end up with two instances and you Singleton strategy will break