Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关于继承和接口的设计混乱_Java - Fatal编程技术网

Java 关于继承和接口的设计混乱

Java 关于继承和接口的设计混乱,java,Java,我遇到了一个相当奇特的设计问题。我正在使用Java ORM,并定义了一个模型类,如下所示: class User extends Model { // . . . } 现在,有更多的模型,我希望它们都支持数据验证。想法很简单:在调用每个setter方法时,内部ArrayList错误不断填充 现在,所有模型类的错误处理机制都完全相同。我可以设想以下界面: public interface ErrorReportable { ArrayList<String> erro

我遇到了一个相当奇特的设计问题。我正在使用Java ORM,并定义了一个模型类,如下所示:

class User extends Model {
    // . . .
}
现在,有更多的模型,我希望它们都支持数据验证。想法很简单:在调用每个setter方法时,内部
ArrayList
错误不断填充

现在,所有模型类的错误处理机制都完全相同。我可以设想以下界面:

public interface ErrorReportable {
    ArrayList<String> errors = new ArrayList<String>();

    boolean hasErrors();

    ArrayList<String> getErrors();

    void resetErrors();
}
公共接口错误报告{
ArrayList errors=新建ArrayList();
布尔hasErrors();
ArrayList getErrors();
void resetErrors();
}
现在我有一个问题:所有的方法都是抽象的,这意味着我必须在我的类中为它们提供一个实现。这是可悲的,因为所有这些方法都将以完全相同的方式实现。理想情况下,这将是另一个我可以很好地继承的类,但遗憾的是,Java中没有多重继承

我的下一个选项是在接口中使用默认方法,但这里的问题是
errors
字段,它将变成静态的,而我需要为每个实例使用一个常规字段

看起来唯一的解决方案是合成,但是我必须在
User
上有一个
hasrerrors()
方法,它将
返回这个.error\u obj.hasrerrors()
。这很好,但在我看来不是很整洁,因为我不得不写两遍


如何才能做得更好?

如果我正确理解您的需求,我将实现一个自己的模型类,它实现所有必要的接口并扩展模型祖先,但仍然是抽象的

然后,所有普通模型类都从抽象模型类继承,以获得接口的实现以及模型类的继承(第二代)。任何使用“instance of”进行检查的框架对于后面的模型类仍将检查true

抽象类甚至不必有任何抽象方法/成员,但它应该保持抽象,以防止从该类直接实例化

public abstract class myModel extends Model implements ErrorReportable{ ... }

public class User extends myModel { ... }

我认为模型类最好只公开
List validate()
方法,并且有一个独立的验证器来验证所有字段并收集错误

这样,收集的消息就不是模型状态的一部分,您可以明确控制何时进行验证,您更喜欢组合(这几乎总是一件好事),并且您需要在模型类中实现的唯一方法是特定于实体的验证


如果您需要添加任何跨域验证,那么扩展此设计以与域验证一起执行这些验证可能非常容易。

您真的希望在setter中立即运行验证吗?如果setter被调用两次,并且在第一次调用时提供无效值,但在第二次调用时提供有效值,该怎么办?此外,如果您最终需要跨域验证,那么在setters中验证将成为一场噩梦。@JiriTousek,据我所知,这不会发生。这是一个典型的web应用程序,控制器将逐个填充字段。最后,控制器将调用
hasrerrors()
,并将响应发送回前端。在下一个周期中,当正确的数据出现时,将实例化一个新对象。但即使我选择按需运行验证,我认为设计难题仍然是一样的。非常好!我觉得这个解决方案就快到了,但是为什么要用抽象类呢?这些方法都不是抽象的。对于所有模型,它们都具有完全相同的实现。因此,我认为如果我定义一个普通类,它会起作用吗?如果你想防止myModel类在野外出现(因为它可能不符合逻辑,使用myModel的实例而不是class User的实例),你应该使用一个抽象类。你不需要它是抽象的,但是你可以阻止调用该设计类的构造函数,它没有任何方面可以让它成为一个实例。这很有意义!我被跨领域验证的想法说服了。由于模型将具有关系,因此如果两个类都具有嵌入式验证器,则会有所帮助。