什么是使用空摘要 class 的好替代方法?
What is a good alternative to using an empty abstract class?
假设我有以下内容:
public abstract class AbstractResponse {
// this class is totally empty!
}
public class ResponseA extends AbstractResponse {
// JSON POJO
}
public class ResponseB extends AbstractResponse {
// JSON POJO
}
public abstract class AbstractClient {
public abstract Class getType();
public AbstractResponse readResponse() {
ObjectMapper mapper = new ObjectMapper();
AbstractResponse response;
try {
return (AbstractResponse) mapper.readValue(data, getType());
} catch (IOException e) {...}
}
}
public class ResponseAClient extends AbstractClient {
public Class getType() {
return ResponseA.class;
}
}
public class ResponseBClient extends AbstractClient {
public Class getType() {
return ResponseB.class;
}
}
ResponseA
和 ResponseB
除了是 JSON POJO 之外没有任何共同点。如您所见,我使用空摘要 class AbstractResponse
来避免客户端 classes ResponseAClient
和 ResponseBClient
中 readResponse()
的重复代码.
我的问题:
在类似情况下使用空摘要 class 是一种不好的做法吗?如果是,最好的编码方式是什么?我考虑过使用泛型,但我看到许多警告不鼓励使用 Java 泛型。
编辑: 感谢大家的快速回复。在@Kayaman 发表有用的评论后,我想这样重新表述我的问题:
对于我上面描述的那种情况,是否有比使用空 interface/abstract class 更好的实现方式。空 interface/abstract class.
似乎是不好的做法
使用界面。使用空抽象 class 是没有意义的(除非你想防止 classes 子class 另一个 class)。
至于你的 "many warnings that discourage the use of Java Generics.",我很乐意看到一些链接,因为那不是真的。
编辑:通用方法可以为您提供如下内容(Response
是一个空接口,用于标记具体响应 classes 并限制 Client
可以处理的允许类型)
public class Client<T extends Response> {
private Class<T> clazz;
public Client(Class<T> clazz) {
this.clazz = clazz;
}
public T readResponse() {
ObjectMapper mapper = new ObjectMapper();
return (T) mapper.readValue(data, clazz);
}
}
允许您处理强类型的响应。
Client<ResponseA> clientA = new Client<>(ResponseA.class);
ResponseA resp = clientA.readResponse();
所以问题"What's a good alternative to an empty abstract class"的答案是"Refactor and Redesign"。
我宁愿使用带有 @Retention(RetentionPolicy.RUNTIME)
的注释,而不是使用空接口或抽象 class。不过,这需要编写更多的代码,并且可能不是特别可读和快速(您要检查 class 是否具有此注释的部分)。
语言中存在空接口,例如Serializable
。但是自从 Java 5 之后,它就不再有意义了。
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public abstract class AbstractClient {
public abstract Class getType();
public Object readResponse() {
ObjectMapper mapper = new ObjectMapper();
try {
Object response = mapper.readValue(data, getType());
if (response.getClass().getDeclaredAnnotation(Response.class) == null) {
// Not a valid type
}
return response;
} catch (IOException e) {...}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Response {
}
@Response
class ResponseA extends AbstractResponse {
// JSON POJO
}
@Response
class ResponseB extends AbstractResponse {
// JSON POJO
}
class ResponseAClient extends AbstractClient {
public Class getType() {
return ResponseA.class;
}
}
class ResponseBClient extends AbstractClient {
public Class getType() {
return ResponseB.class;
}
}
假设我有以下内容:
public abstract class AbstractResponse {
// this class is totally empty!
}
public class ResponseA extends AbstractResponse {
// JSON POJO
}
public class ResponseB extends AbstractResponse {
// JSON POJO
}
public abstract class AbstractClient {
public abstract Class getType();
public AbstractResponse readResponse() {
ObjectMapper mapper = new ObjectMapper();
AbstractResponse response;
try {
return (AbstractResponse) mapper.readValue(data, getType());
} catch (IOException e) {...}
}
}
public class ResponseAClient extends AbstractClient {
public Class getType() {
return ResponseA.class;
}
}
public class ResponseBClient extends AbstractClient {
public Class getType() {
return ResponseB.class;
}
}
ResponseA
和 ResponseB
除了是 JSON POJO 之外没有任何共同点。如您所见,我使用空摘要 class AbstractResponse
来避免客户端 classes ResponseAClient
和 ResponseBClient
中 readResponse()
的重复代码.
我的问题:
在类似情况下使用空摘要 class 是一种不好的做法吗?如果是,最好的编码方式是什么?我考虑过使用泛型,但我看到许多警告不鼓励使用 Java 泛型。
编辑: 感谢大家的快速回复。在@Kayaman 发表有用的评论后,我想这样重新表述我的问题:
对于我上面描述的那种情况,是否有比使用空 interface/abstract class 更好的实现方式。空 interface/abstract class.
似乎是不好的做法使用界面。使用空抽象 class 是没有意义的(除非你想防止 classes 子class 另一个 class)。
至于你的 "many warnings that discourage the use of Java Generics.",我很乐意看到一些链接,因为那不是真的。
编辑:通用方法可以为您提供如下内容(Response
是一个空接口,用于标记具体响应 classes 并限制 Client
可以处理的允许类型)
public class Client<T extends Response> {
private Class<T> clazz;
public Client(Class<T> clazz) {
this.clazz = clazz;
}
public T readResponse() {
ObjectMapper mapper = new ObjectMapper();
return (T) mapper.readValue(data, clazz);
}
}
允许您处理强类型的响应。
Client<ResponseA> clientA = new Client<>(ResponseA.class);
ResponseA resp = clientA.readResponse();
所以问题"What's a good alternative to an empty abstract class"的答案是"Refactor and Redesign"。
我宁愿使用带有 @Retention(RetentionPolicy.RUNTIME)
的注释,而不是使用空接口或抽象 class。不过,这需要编写更多的代码,并且可能不是特别可读和快速(您要检查 class 是否具有此注释的部分)。
语言中存在空接口,例如Serializable
。但是自从 Java 5 之后,它就不再有意义了。
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public abstract class AbstractClient {
public abstract Class getType();
public Object readResponse() {
ObjectMapper mapper = new ObjectMapper();
try {
Object response = mapper.readValue(data, getType());
if (response.getClass().getDeclaredAnnotation(Response.class) == null) {
// Not a valid type
}
return response;
} catch (IOException e) {...}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Response {
}
@Response
class ResponseA extends AbstractResponse {
// JSON POJO
}
@Response
class ResponseB extends AbstractResponse {
// JSON POJO
}
class ResponseAClient extends AbstractClient {
public Class getType() {
return ResponseA.class;
}
}
class ResponseBClient extends AbstractClient {
public Class getType() {
return ResponseB.class;
}
}