Whiteship's Note


[AspectJ] Extension and Implementation

AOP : 2009.06.08 20:16


http://www.eclipse.org/aspectj/doc/released/progguide/semantics-declare.html#extension-and-implementation

    declare parents: EmpDao extends GenericDao<Emp, EmpParams>;
    declare parents: EmpDaoImpl extends HibernateGenericDao<Emp, EmpParams>;
    declare @type: EmpDaoImpl: @org.springframework.stereotype.Repository;

EmpDao 클래스가 GenericDao 클래스를 상속 받도록 설정.
EmpDaoImpl 클래스가 HibernateGenericDao 클래스를 상속 받도록 설정.
EmpDaoImpl 클래스에 @Repository 애노테이션 추가.

문법이 복잡해 보였는데 막상 사용해보니 간단 간단 하네요.

public interface EmpDao {

}

public class EmpDaoImpl implements EmpDao {

}

이런 기초적인 코드만 존재하지만..

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml", "/applicationContext-datasource.xml"})
@Transactional
public class EmpDaoImplTest {

    @Autowired
    EmpDaoImpl daoImpl;

    @Test
    public void daoInterface() throws Exception {
        assertNotNull(daoImpl);
        daoImpl = new EmpDaoImpl();
        GenericDao<Emp, EmpParams> gdao = daoImpl;
        HibernateGenericDao<Emp, EmpParams> hgdao = daoImpl;
    }

    @Test
    public void crud() throws Exception {
        Emp emp = new Emp();
        daoImpl.add(emp);
        daoImpl.flush();
        assertEquals(1, daoImpl.getAll().size());
    }

}

이런 테스트를 돌릴 수 있다는거...



top


EJ2E Item 20. 태그가 있는 클래스 대신 클래스 계층구조를 선호하라.

Java : 2009.03.13 20:09


참조: Effective Java 2nd Edition. Prefer class hierarchies to tageed classes

사용자 삽입 이미지

위와 같은 클래스의 단점:
- enum, switch 문, 태그 필드로 인해 지져분하다.
- 여러 구현체를 하나의 클래스로 합쳐놓았기 때문에 가독성이 떨어진다.
- 불필요한 필드까지 가지고 인스턴스를 만들어야 하기 떄문에 메모리 풋프린트가 증가한다.
- 생성자에서 불필요한 필드까지 초기화하지 않는 이상 필드를 final로 선언할 수 없다.
- 생성자에서 초기화를 잘못했을 때 컴파일 시점에 이것을 알 수 없다.
- 새로운 종류를 추가했을 때 switch문에 case를 추가해야 한다는 것을 기억해야 한다. 안그러면 런타임 에러가 발생한다.
- 인스턴스 데이터 타입이 실제 타입을 알려주지 못한다.
=> 즉 장황하고, 에러가 발생할 여지가 많고, 비효율적이다.

먼저 추상 클래스를 만들어서 일반적인 것들을 이 클래스로 이동시키고,
구체적인 하위 클래스를 정의한다.
해당 하위 클래스에서 추상 매서드를 구현한다.

사용자 삽입 이미지

이렇게 구성하면
- 깨끗하고 간단하다.
- 특정 타입에 관련된 속성은 해다 클래스가 가지게 된다. 따라서 불필요한 필드가 없다.
- 모든 필드를 final로 선언할 수 있다.
- 컴파일 시점에 생성자에서 데이터 필드를 초기화 하는지, 추상 매서드를 구현했는지 확인할 수 있다.

top


상속에 대하여...

Java : 2006.11.20 11:07


Agile Java 스터디에서 상속에 대한 논의가 시작되었습니다. 논의는 처음 상속이 필요한가? 아니면 지양해야 하는가? 이렇게 시작을 하려했지만 이미 그러한 논의는 옛날 부터 있었던 것이고 Object-Based가 아닌 Object-Oriented에서는 상속이 특징으로 꼽히기 때문에 굳이 유용한 기능을 지양할 필요는 없다고 생각합니다. API에서도 이미 상속을 사용하여 많은 클래스들을 구현해 놓았고 다형성은 어떻게 할 것이며 제네릭 같은 템플릿은 상속이 없으면 과연 존재 의미가 있기나 한건지 생각하게 됩니다. 아 다시 생각해보니 제네릭과 상속은 별 상관이 없겠네요. 콜렉션의 타입을 제약하는 기능을 하는거기 때문에 하지만 역시 다형성을 사용못한다는 건 큰 손실이라고 생각이 됩니다.

Situation

그래서 인지 아닌지 논의의 초점은 바뀌었습니다. Abstract 클래스만을 상속하도록 제한되어야 하는가? 아니면 어떤 클래스든 상속을 자유롭게 사용해야 하는가?로  바뀌었습니다. 이 둘중에 어느 한쪽 만을 굳이 선택해야 한다면 전 자유로운 상속을 택하겠습니다. 둘의 가장 큰 차이는 상위 타입의 객체를 만들 수 있느냐 없느냐인 것 같은데 물론 경우에 따라서 상위 타입의 객체 생성을 자제 해야하는 경우도 있겠지만 Abstract 클래스만 상속하도록 제한한다면 개발이 형식에 얽매여서 필요없는 일까지 하게될 상황이 발생하게 될 수 있다는 생각을 해봅니다.

Abstact 클래스만 상속하도록 바껴야 한다. 라는 규율? 규칙이 있는 환경에서 개발을 한다고 생각해보면 다음과 같은 클래스 구조가 생길 것입니다.
어디선가는 객체를 써야 하기 때문에 결국 클래스를 만들게 되겠지요. 이렇게 시스템을 만들어 둔 상태에서 새로운 요구사항이 생겨서 정삼각형, 직각 삼각형 등을 추가하게 됐다면 어떻게 고쳐야 할까요?

상속을 자유롭게 사용하자

당연히 이렇게 되어야 한다고 생각합니다. 기존에 Triangle 객체를 사용하던 사람들도 여전히 사용할 수 있고 새로 추가된 RegularTriangle과 RightTriangle 객체도 사용할 수 있게됐으니 말이죠.

Abstract 클래스만 상속해야 한다.

하지만 Abstract 클래스만 상속 받아야 한다면 어떻게 해야할까요?
이렇게 하지 않을까요? 이렇게 하면 기존의 Triangle에 있던 멤버들과 중복이 발생하게 되는 것 아닐까요? 아니면 다음과 같이 기존의 Triangle 클래스를 Abstract로 바꿀수도 있습니다.(주로 성일이형이 말씀하시던게 바로 이 그림이 아닐런지 생각해 봅니다.)
이렇게 되면 Triangle에 있는 자원을 재사용 할 수 있게 되어 괜찮지 않을까 생각할 수 있지만 기존에 Triangle 클래스를 사용하던 소스코드들은 그럼 전부 어떻게 되는거죠? 따라서 Abstract 클래스만 상속을 하도록 제약하는 것은 개발을 너무 힘들게 하는 일이라고 생각합니다.


top