如何强制实施 API Java
How to force an implementation for an API Java
我们有关于 API 设计的问题。它在我的头上钻了一个洞,我想不通。
举例来说,我有一个带有一种方法的接口,用于读取文件,但您需要传递某种凭据,所以这里的对象实际上可以是任何 pojo。
public interface Reader(){
public void read(String identifier, Object credentials);
}
问题是如果开发人员扩展它来实现凭据,我该如何强制他们确保它是有效的凭据而不是绕过它。以下是我建议的解决方案:
public boolean authenticate(Object credentials);
或者,它可能是这样的
public Object authenticate(Object credentials);
我也试过这种方式,所以它给了一个默认的认证
public interface Auth {
default boolean authenticate() {
//do real authentication
return true;
}
}
以及我将传递给 Reader
接口的响应,他们回来说我说开发人员也可以随时忽略它,只说 return true
。而这一切都是错误的。
他们暗示答案与Abstract classes
有关,但我在想如果它是一个抽象的class,是不是意味着如果我扩展了就不意味着我仍然可以重写这个方法吗?然后说 return true
还在吗?
abstract class Auth {
public boolean authenticate(Object o) {
//some real authentication
return boolean ;
}
}
//developer implementation
class extends AuthImpl extends Auth{
public boolean authenticate(Object o){
return true;
}
}
这是一个小组讨论,他们都同意有一种方法可以让开发人员不能只 return 对摘要进行 true 处理。我在这里错过了什么?我如何强制开发人员正确实施实际身份验证,而不仅仅是 returning true?请帮助似乎无法解决这个问题
我认为他们希望看到以下合同模式:
public abstract class Reader(){
// Requirement to implement:
protected abstract void authenticate(Object credentials);
// Requirement to implement:
protected abstract void actuallyRead(BufferedReader in, String identifier,
Object credentials) throws IOException;
// Service provided:
public final void read(String identifier, Object credentials) {
... using authenticate and actuallyRead ...
}
}
客户端开发人员 仅具有 API 的 read
功能。但是 实现者 必须提供功能 (authenticate, actuallyRead
)。用作 API 创建者 指定的。
注意 actuallyRead
可以传递(提供)和 return(需要)额外信息。
如果你想强制实施,你必须有一个 class,抽象与否。当然 authenticate
会变成 final
所以它不能被覆盖(当然,如果你是开发者,没有什么能阻止你把它变成非最终的,所以它变得有点学术化了真的能保证安全)。
一种方法是只将外部的 Reader 实现作为参数,这样开发人员可以自由实现读取,但系统的其余部分总是到处使用 AuthReader
(这会直接依赖于身份验证,绕过它要困难得多,因为它需要更改所有使用它的地方)。这允许读取的灵活性,但身份验证的安全性。
像这样
public final class AuthReader implements Reader {
private Reader reader;
private Object credentials;
public AuthReader(Reader reader, Object credentials) {
this.reader = reader;
this.credentials = Objects.requireNonNull(credentials);
}
private boolean isAuthenticated() {
... // authenticate credentials
}
public String readString() {
if(!isAuthenticated())
throw new SecurityException();
return reader.readString();
}
}
在编译时确保凭据
假设您只允许使用有效凭据实例化 Authorized 实例。
假设你有这个:
public final class Authorized {
private final Object credentials;
public abstract class Reader {
}
public Authorized(Object credentials) {
if (credentials == null) {
Objects.requireNonNull(credentials, "Missing credentials");
}
this.credentials = credentials;
}
}
这样你可以从 Reader 扩展,但是你不能从 Reader 实例化一个超类,而 没有 [=] 的实例12=].
示例:
public class MyReader extends Authorized.Reader {
public MyReader() {
// YOU MUST CALL .super() HERE ON A
// INSTANCE OF Authroized or you can not compile.
}
}
- 在 MyReader 的默认构造函数中,您必须使用 Authroized 的实例,例如
new Authorized("").super()
.
- 不能继承
Authroized
重写构造函数
- 如果没有
Authroized
. 的实例,则无法创建 MyReader 的实例
经过深思熟虑并根据此处的所有答案,我认为这就是他们的意思。感谢@Kayaman 的回答引导了正确的方向。
通过abstract
就是这样,因为你强加了Reader
有1个参数constructor
他不能实例化它,他被迫放一个super
调用他的实现。
abstract class Reader {
protected Object authentication;
ReaderImpl(Object authentication) throws Exception{
if(null == authentication){
throw new Exception();
}else{
this.authentication = authentication;
}
}
public void reader(String x, Object authentication) {
System.out.println("Reader Implemented");
}
}
class DevReader extends Reader{
public DevReader(Object authentication) throws Exception{
super(authentication);
}
@Override
public void reader(String x, Object authentication) {
System.out.println("Dev Implemented");
}
}
我们有关于 API 设计的问题。它在我的头上钻了一个洞,我想不通。
举例来说,我有一个带有一种方法的接口,用于读取文件,但您需要传递某种凭据,所以这里的对象实际上可以是任何 pojo。
public interface Reader(){
public void read(String identifier, Object credentials);
}
问题是如果开发人员扩展它来实现凭据,我该如何强制他们确保它是有效的凭据而不是绕过它。以下是我建议的解决方案:
public boolean authenticate(Object credentials);
或者,它可能是这样的
public Object authenticate(Object credentials);
我也试过这种方式,所以它给了一个默认的认证
public interface Auth {
default boolean authenticate() {
//do real authentication
return true;
}
}
以及我将传递给 Reader
接口的响应,他们回来说我说开发人员也可以随时忽略它,只说 return true
。而这一切都是错误的。
他们暗示答案与Abstract classes
有关,但我在想如果它是一个抽象的class,是不是意味着如果我扩展了就不意味着我仍然可以重写这个方法吗?然后说 return true
还在吗?
abstract class Auth {
public boolean authenticate(Object o) {
//some real authentication
return boolean ;
}
}
//developer implementation
class extends AuthImpl extends Auth{
public boolean authenticate(Object o){
return true;
}
}
这是一个小组讨论,他们都同意有一种方法可以让开发人员不能只 return 对摘要进行 true 处理。我在这里错过了什么?我如何强制开发人员正确实施实际身份验证,而不仅仅是 returning true?请帮助似乎无法解决这个问题
我认为他们希望看到以下合同模式:
public abstract class Reader(){
// Requirement to implement:
protected abstract void authenticate(Object credentials);
// Requirement to implement:
protected abstract void actuallyRead(BufferedReader in, String identifier,
Object credentials) throws IOException;
// Service provided:
public final void read(String identifier, Object credentials) {
... using authenticate and actuallyRead ...
}
}
客户端开发人员 仅具有 API 的 read
功能。但是 实现者 必须提供功能 (authenticate, actuallyRead
)。用作 API 创建者 指定的。
注意 actuallyRead
可以传递(提供)和 return(需要)额外信息。
如果你想强制实施,你必须有一个 class,抽象与否。当然 authenticate
会变成 final
所以它不能被覆盖(当然,如果你是开发者,没有什么能阻止你把它变成非最终的,所以它变得有点学术化了真的能保证安全)。
一种方法是只将外部的 Reader 实现作为参数,这样开发人员可以自由实现读取,但系统的其余部分总是到处使用 AuthReader
(这会直接依赖于身份验证,绕过它要困难得多,因为它需要更改所有使用它的地方)。这允许读取的灵活性,但身份验证的安全性。
像这样
public final class AuthReader implements Reader {
private Reader reader;
private Object credentials;
public AuthReader(Reader reader, Object credentials) {
this.reader = reader;
this.credentials = Objects.requireNonNull(credentials);
}
private boolean isAuthenticated() {
... // authenticate credentials
}
public String readString() {
if(!isAuthenticated())
throw new SecurityException();
return reader.readString();
}
}
在编译时确保凭据
假设您只允许使用有效凭据实例化 Authorized 实例。
假设你有这个:
public final class Authorized {
private final Object credentials;
public abstract class Reader {
}
public Authorized(Object credentials) {
if (credentials == null) {
Objects.requireNonNull(credentials, "Missing credentials");
}
this.credentials = credentials;
}
}
这样你可以从 Reader 扩展,但是你不能从 Reader 实例化一个超类,而 没有 [=] 的实例12=].
示例:
public class MyReader extends Authorized.Reader {
public MyReader() {
// YOU MUST CALL .super() HERE ON A
// INSTANCE OF Authroized or you can not compile.
}
}
- 在 MyReader 的默认构造函数中,您必须使用 Authroized 的实例,例如
new Authorized("").super()
. - 不能继承
Authroized
重写构造函数 - 如果没有
Authroized
. 的实例,则无法创建 MyReader 的实例
经过深思熟虑并根据此处的所有答案,我认为这就是他们的意思。感谢@Kayaman 的回答引导了正确的方向。
通过abstract
就是这样,因为你强加了Reader
有1个参数constructor
他不能实例化它,他被迫放一个super
调用他的实现。
abstract class Reader {
protected Object authentication;
ReaderImpl(Object authentication) throws Exception{
if(null == authentication){
throw new Exception();
}else{
this.authentication = authentication;
}
}
public void reader(String x, Object authentication) {
System.out.println("Reader Implemented");
}
}
class DevReader extends Reader{
public DevReader(Object authentication) throws Exception{
super(authentication);
}
@Override
public void reader(String x, Object authentication) {
System.out.println("Dev Implemented");
}
}