关于继承和接口的设计混淆

时间:2016-12-07 14:30:03

标签: java

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

class User extends Model {
    // . . .
}

现在,有更多型号,我希望它们都支持数据验证。这个想法很简单:在调用每个setter方法时,内部ArrayList个错误会不断填充。

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

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

    boolean hasErrors();

    ArrayList<String> getErrors();

    void resetErrors();
}

现在我遇到了一个问题:所有的方法都是抽象的,这意味着我必须在我的类中为它们提供一个实现。这很难过,因为所有这些方法都将以完全相同的方式实现。理想情况下,这将是我可以巧妙地继承的另一个类,但遗憾的是,Java中没有多重继承。

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

看起来唯一的解决方案是组合,但是我必须在hasErrors()上使用User方法,该方法将return this.error_obj.hasErrors() User::chunk(200, function($users) { foreach ($users as $user) { // } }); 。这很好,但在我看来并不是很整洁,因为我不得不两次写东西。

我怎样才能做得更好?

2 个答案:

答案 0 :(得分:1)

如果我的需要正确,我会实现一个自己的Model-class,它实现所有neceaasary接口并扩展Model-ancestor,但仍然是Abstract。

然后,所有正常的模型类都从您的抽象模型类继承,以获得接口的实现以及模型类的继承(第二代就是这样)。任何框架检查&#39;实例&#39;对于后来的模型类,它仍然会检查为真。

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

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

public class User extends myModel { ... }

答案 1 :(得分:1)

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

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

如果您需要添加任何跨字段验证,那么扩展此设计也可以很容易地执行那些与字段验证一起使用。