实施平等合同的正确方法 [英] Right way to implement equals contract

查看:17
本文介绍了实施平等合同的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 User 的域对象.用户的属性包括 ssoId、姓名、电子邮件、createdBy、createdDate 和 userRole.其中,ssoId 必须是唯一的,因为没有两个用户可以拥有相同的 sso id.所以我的 equals 方法检查 sso id 并返回 true 或 false.

I have a domain object called User. Properties of user include ssoId, name, email, createdBy, createdDate and userRole. Of these, ssoId must be unique in the sense no two users can have the same sso id. So my equals method checks for the sso id and returns either true or false.

@Override public boolean equals(Object o) {
    if (!(o instanceof User))
      return false;
    return user.getSsoId().equals((User)o.getSsoId());
}

我觉得这是一个不正确的实现,尽管就业务规则而言它是正确的.对于具有相同 sso id 但名称或电子邮件或两者具有不同值的两个对象,上述实现将返回 true.我应该更改我的 equals 合同以检查所有字段的相等性吗?您有什么建议?

What I feel is that this is an incorrect implementation, though it is correct as far as the business rules are concerned. The above implementation will return true for two objects with same sso id but with different values for say name or email or both. Should I change my equals contract to check the equality of all fields? What is your suggestion?

推荐答案

这对于技术平等"来说(几乎)是正确的,但对于自然平等"来说则不然.为了实现顶级技术平等,您还应该测试自反 o == this.可能会发生该对象尚未保存在 DB 中,因此还没有技术 ID.例如

This is (almost) correct for "technical equality", but not for "natural equality". To achieve top technical equality, you should also test the reflexive o == this. It may happen that the object isn't persisted in DB yet and thus doesn't have a technical ID yet. E.g.

public class User {

    private Long id;

    @Override
    public boolean equals(Object object) {
        return (object instanceof User) && (id != null) 
             ? id.equals(((User) object).id) 
             : (object == this);
    }

    @Override
    public int hashCode() {
        return (id != null)
             ? (User.class.hashCode() + id.hashCode())
             : super.hashCode();
    }

}

为了自然平等"您应该比较所有非技术属性.对于现实世界实体"这毕竟比技术平等更强大(但也更昂贵).

For "natural equality" you should rather compare all non-technical properties. For "real world entities" this is after all more robust (but also more expensive) than technical equality.

public class User {

    private String name;
    private Date birth;
    private int housenumber;
    private long phonenumber;

    @Override
    public boolean equals(Object object) {
        // Basic checks.
        if (object == this) return true;
        if (!(object instanceof User)) return false;

        // Property checks.
        User other = (User) object;
        return Objects.equals(name, other.name)
            && Objects.equals(birth, other.birth)
            && (housenumber == other.housenumber)
            && (phonenumber == other.phonenumber);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, birth, housenumber, phonenumber);
    }

}

是的,当有很多属性时,这会是很多代码.一个不错的 IDE(Eclipse、Netbeans 等)可以自动生成 equals()hashCode()(还有 toString()、getter和二传手)给你.从中受益.在 Eclipse 中,右键单击代码并查看 Source (Alt+Shift+S) 菜单选项.

True, that's lot of code when there are a lot of properties. A bit decent IDE (Eclipse, Netbeans, etc) can just autogenerate equals(), hashCode() (and also toString(), getters and setters) for you. Take benefit of it. In Eclipse, rightclick code and peek the Source (Alt+Shift+S) menu option.

这篇关于实施平等合同的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆