BaseObject.java
  Dashboard > Java와 JEE > Home > BaseObject.java
Community
  Java와 JEE Log In | Sign Up   View a printable version of the current page.  
Added by 박재성, last edited by 박재성 on 4월 30, 2007  (view change)
Labels: 
(None)

BaseObject.java와의 첫만남.

  • BaseObject.java는 Appfuse 프로젝트를 분석하면서 알게된 클래스로 생각된다. 그 동안 상당히 짜증나는 작업이였던 equals(), hashCode(), toString() 메써드를 자바 Reflection 기능을 이용하여 자동화해주고 있었다.
  • BaseObject.java와 첫번째 만났을 때의 소스코드는 다음과 같았다.
BaseObject.java
import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class BaseObject implements Serializable {
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}

	public boolean equals(Object o) {
		return EqualsBuilder.reflectionEquals(this, o);
	}

	public int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}
}
  • Apache Commons Lang에서 제공하는 Builder 클래스들을 이용하여 equals(), hashCode(), toString() 세개의 메써드를 손쉽게 구현하는 것이 너무 좋아보였다.
  • 그러나 문제는 Hibernate 프레임워크를 이용하여 프로젝트를 진행할 때 위처럼 API를 사용할 경우 무한 루프에 빠지는 경우가 종종 발생했다. 그 때마다 원인을 찾아 해결하는 일이 오히려 더 짜증나는 작업이 되었다.

BaseObject.java와의 두번째 만남

  • 모든 작업에는 Trade Off가 있기 마련이듯 프로그래밍에 완전한 자동화란 불가능한 것이 아닐까라는 생각이 든다. 최근에 발표되는 EquinoxAppFuse의 소스를 분석한 결과 두 프로젝트 모두 BaseObject.java를 포함하고 있다. 그러나 그 둘의 구현은 다르다.
Equinox 1.7의 BaseObject.java
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import java.io.Serializable;

/**
 * Base class for Model objects.  This is basically for the toString method.
 *
 * @author Matt Raible
 */
public class BaseObject implements Serializable {
    private static final long serialVersionUID = 3256446889040622647L;

    public String toString() {
        return ToStringBuilder.reflectionToString(this,
                ToStringStyle.MULTI_LINE_STYLE);
    }
}
Appfuse 1.9.4의 BaseObject.java
import java.io.Serializable;


/**
 * Base class for Model objects.  Child objects should implement toString(), 
 * equals() and hashCode();
 *
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 */
public abstract class BaseObject implements Serializable {    
    public abstract String toString();
    public abstract boolean equals(Object o);
    public abstract int hashCode();
}
  • 구현한 개발자가 같음에도 BaseObject.java의 구현이 다른 이유는 BaseObject.java의 구현에 대하여 지속적으로 고민하고 있다는 증거일 것이라 생각한다. 나도 지금까지 제일 첫번째 형태의 BaseObject.java를 아직까지 사용하고 있는데 지금까지 사용하면서 불편함이 있음에도 불구하고 사용했다는 생각이 든다.
  • 오히려 현재 변화발전해 온 위 두개의 BaseObject.java 모습이 더 좋지 않을까? 위 세개의 메써드가 필요하다는 것을 잘 알면서도 구현하지 않는 개발자들에게 단순하게 인터페이스를 통하여 강제하는 방식이 가장 좋은 방법일지도 모르겠다. 모든 프로그래밍에 정답은 없다.

equals(), hashCode(), toString() 메써드 구현

  • 이 세개의 메써드는 구현할 때마다 샘플 소스를 찾는지라 이 참에 이곳에 정리해놔야겠다. 아무래도 앞으로도 유용하게 쓸 수 있는 기회가 많을 듯 싶다.

equals() 메써드

equals() 메써드를 수동으로 구현
public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Address)) return false;

        final Address address1 = (Address) o;

        if (address != null ? !address.equals(address1.address) : address1.address != null) return false;
        if (city != null ? !city.equals(address1.city) : address1.city != null) return false;
        if (country != null ? !country.equals(address1.country) : address1.country != null) return false;
        if (postalCode != null ? !postalCode.equals(address1.postalCode) : address1.postalCode != null) return false;
        if (province != null ? !province.equals(address1.province) : address1.province != null) return false;

        return true;
    }

hashCode() 메써드

hashCode() 메써드를 수동으로 구현
public int hashCode() {
        int result;
        result = (address != null ? address.hashCode() : 0);
        result = 29 * result + (city != null ? city.hashCode() : 0);
        result = 29 * result + (province != null ? province.hashCode() : 0);
        result = 29 * result + (country != null ? country.hashCode() : 0);
        result = 29 * result + (postalCode != null ? postalCode.hashCode() : 0);
        return result;
    }

toString() 메써드

ToStringBuilder를 이용하여 toString() 메써드 구현
public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
                .append("country", this.country)
                .append("address", this.address).append("province",
                        this.province).append("postalCode", this.postalCode)
                .append("city", this.city).toString();
    }

Site running on a free Atlassian Confluence Open Source Project License granted to JavaJiGi Project. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.1 Build:#643 1월 22, 2007) - Bug/feature request - Contact Administrators