본문 바로가기
  • 오늘도 한걸음. 수고많았어요.^^
  • 조금씩 꾸준히 오래 가자.ㅎ
IT기술/JAVA

[java] pojo란 무엇인가?(Plain Old Java Object)

by 미노드 2023. 7. 20.

작업을 하다가 뜬금없이 pojo 라는 단어를 듣게 되었다.

고유명사인가? 무슨 의미가 있나 싶어서 찾아봤는데, Plain Old Java Object 의 줄임말로써 
마틴 파울러 라는 사람이 고안한 "오래된 순수한 자바 객체", "그저 자바 객체" 라는 의미로서 사용되는 것 같다.

pojo라는 개념이 개발하는데 왜 쓰이는가? 굳이 쓸 필요가 있을까?
이런거 모르고서도 잘만 개발해왔는데,
판단하기 위해 pojo가 뭔지 정리해보려한다.

pojo가 뭘까?

pojo란, 이름 그대로 "순수한 객체, 보통 객체, 간단한 객체"를 의미한다.
Java EE 등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 "무거운" 객체를 만들게 된 것에 반발해서 사용되게 된 용어이다. 2000년 9월에 마틴 파울러, 레베카 파슨, 조쉬 맥킨지 등이 사용하기 시작한 용어로서 마틴 파울러는 다음과 같이 그 기원을 밝히고 있다. [위키백과]

“우리는 사람들이 자기네 시스템에 보통의 객체를 사용하는 것을 왜 그렇게 반대하는지 궁금하였는데, 간단한 객체는 폼 나는 명칭이 없기 때문에 그랬던 것이라고 결론지었다. 그래서 적당한 이름을 하나 만들어 붙였더니, 아 글쎄, 다들 좋아하더라고. ”
— 마틴 파울러

쉽게말하면, java EE에 종속적인 참조가 없는 순수한 자바 객체를 의미한다.
샘플을 만들어 보면 getter, setter 가 준비된 순수 객체를 말한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Book {
    private String title;
    private String author;
    
    public Book() {}
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }
    
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public void showInfo() {
        System.out.println(title + ", " + author);
    }
}
cs

하이버네이트

Persistence 기술과 오브젝트-관계형 DB 매핑을 순수한 pojo를 이용해 사용할 수 있게 만드는
pojo기반의 퍼시스턴스 프레임워크.
JDBC API를 직접 사용해 개발하는 것 못지않은 성능과 복잡한 퍼시스턴스 로직을 개발 가능하게 해주었기 때문이다.
그리고 하이버네이트가 사용하는 pojo엔티티들은 객체지향적인 다양한 설계와 구현이 가능하다.

스프링

엔터프라이즈 서비스들을 pojo기반으로 만든 비즈니스 오브젝트에서 사용할 수 있게 해준다.
IoC 컨테이너를 제공해서, 인스턴스들의 라이프 사이클을 관리하고,
특정 인터페이스를 구현하거나 상속할 필요가 없고 라이브러리를 지원하기에 용이하며 객체 또한 가벼운 것이 특징이며,
OOP를 더 OOP답게 쓸 수 있게 해주는 AOP 기술을 적용해서 pojo 개발을 더 쉽게 만들어준다.

POJO 프로그래밍의 가치

단순히 POJO 프레임워크를 사용한다고, POJO 개발을 자연스럽게 하는 것은 아니다.
POJO 기반의 코드인지를 확인하는 두 가지 기준

1. 객체지향적으로 설계 되었는가?

반복적인 템플릿 코드와 테스트하기 힘든 구조, 확장 및 재활용의 어려움이 남아있다면
EJB의 문제점을 여전히 안고 있는 것이다.

2. 테스트가 용이한가?

잘 만들어진 pojo 어플리케이션은 자동화된 테스트 코드 작성이 편리하다.
코드 작성이 편리하면 좀 더 꼼꼼하게 만들게 되고, 코드 검증과 품질 향상에 유리해진다.
또한, 잘 만들어진 테스트 코드베이스가 있다면 리팩토링할 여유가 생겨
pojo 코드를 좀 더 나은 설계구조로 변경할 수 있다.

진정한 pojo 

토비의 스프링에서는 진정한 pojo 를 아래와 같이 정의했다고 합니다.

그럼 특정 기술규약과 환경에 종속되지 않으면 모두 pojo 라고 말할 수 있는가?
많은 개발자가 크게 오해하는 것 중의 하나가 바로 이것이다. . .(중략). .
진정한 pojo 란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고
필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말한다.

그런데 특정 기술에 종속적이면 pojo가 아니라면서 스프링에서 하이버네이트 사용은 어떻게 가능한걸까?
하이버네이트는 스프링에 종속된 상태에서 사용하는데 pojo가 아니지 않나?
바로 스프링에서 정한 표준 인터페이스가 있기 때문이다.
스프링 개발자들은 ORM이라는 기술을 사용하기 위해서 JPA라는 표준 인터페이스를 정해두었고,
여러 ORM 프레임워크들은 이 JPA라는 표준 인터페이스 아래에서 구현되어 실행된다.
하이버네이트를 쓸려면 JPA를 통해서 쓰는 것이다.

이것이 바로 스프링이 새로운 엔터프라이즈 기술을 도입하면서도 pojo를 유지하는 방법이다.
이런 방법을 스프링의 PSA(Portable Service Abstraction)라고 이야기한다.

POJO의 조건

1. 특정 규약에 종속되면 안 된다.

JAVA언어와 꼭 필요한 API 외 다른 것에 종속되면 안 된다. 
특정 Library, Module에서 정의된 클래스를 상속받아서 구현하지 않는다.
pojo가 되기 위해서는 외부의 의존성을 두지 않고 순수한 JAVA로 구성이 가능해야한다.

2. 특정 환경에 종속되면 안 된다.

pojo는 환경에 종속되지 않고 독립적이어야 한다.
예를 들어 웹 기술의 클래스나 인터페이스를 상속받거나 구현하면 해당 객체는 웹 환경에서만 사용가능할 것이다.
이처럼 특정 환경에 종속되어서는 안 된다.
만일 특정 비즈니스 로직을 처리하는 부분에 외부 종속적인 http request, session 등이 있을 경우, pojo를 위배한 것으로 간주한다.

대표적으로 아래 3가지는 pojo가 아닌 경우이다.

(1) 클래스 확장 

public class Foo extends javax.servlet.http.HttpServlet { ...

(2) 인터페이스 구현

public class Bar implements javax.ejb.EntityBean { ...

(3) Annotation 포함

@javax.persistence.Entity public class Baz { ...

 

3. 객체 지향적 원리를 지켜야 한다.

pojo는 자바의 기본인 객체지향적 원리를 지켜야 한다.
하나의 클래스는 하나의 책임과 역할을 갖도록 하는 등 객체지향 설계를 적용해야 진정한 pojo라고 볼 수 있다.