티스토리 뷰

Development

DTO, 팩토리메소드

로글고그로그 2018. 10. 23. 18:53

라임퍼옴

팩토리란 ?

팩토리(Factory) 는 '공장' 이라는 뜻을 가지고 있다.

일반적으로 클래스의 객체를 생성할 때, 생성자 를 통해서 객체를 생성하지만 팩토리 메소드 라는 공장을 통해서 객체를 만들 수도 있다.

 

그럼, 팩토리 메서드를 사용한 것과 생성자를 사용한 것이 무슨 차이가 있는 것 인가요?

굳이 팩토리 메서드를 만들어서 인스턴스를 생성하는 번거로운 작업을 왜 해?

 

이것에 대한 답변을 들어보기 전에, 여러분들도 한 번 고민해 보자

 

 

 

 

 

팩토리 메서드

public class Person{
    private int age;
    public Person(int age){
        this.age = age;
    }
}

이것은 우리가 자바 기본서에서 지겹도록 봐왔던 클래스 구조다.

 

Person p = new Person(10);

그리고 우리는 객체를 생성할 때, 위와 같이 생성자 호출을 통해서 객체를 생성해왔다.

그런데 우리는 생성자의 인자만 봐서는 이것이 나이를 나타내는 것인지, 10 원짜리 동전을 가지고 있다는 것인지 클래스를 뜯어보지 않고서는 도무지 알 길이 없다.

 

하지만 이것을 팩토리 메서드로 구현한다면 어떨까

public class Person{
    private int age;
    private Person(int age){
        this.age = age;
    }
    
    public static Person ofAge(int age){
        return new Person(age);
    }
}
Person p = Person.ofAge(10);

위 코드를 보고 여러분은 인자 값이 '나이' 라는 것을 쉽게 추측할 수 있다. 

또한 생성자를 private 으로 변경해서 팩토리 메서드를 통한 객체 생성을 강제하고 있다.

이것이 팩토리 메서드의 장점이다.

 

팩토리 메서드의 장점

첫 번째 장점은, 생성자와는 달리 팩토리 메서드에는 이름이 있다는 것이다. 생성자는 이것이 어떤 객체가 생성되는지 쉽게 알 수 없지만, 팩토리 메서드는 이름을 잘 지어 놓으면 코드의 가독성이 높아지며 사용하기도 쉬워진다.


두 번째 장점은, 생성자와 달리 호출할 때마다 새로운 객체를 생성할 필요가 없다. 때문에, 동일한 객체가 요청되는 일이 잦고, 객체를 만드는 비용이 클 때 적용시키면 성능을 크게 개선할 수 있다.


세 번째 장점은, 생성자와 달리 반환값 자료형의 하위 자료형 객체를 반환할 수 있다. 따라서 반환되는 객체의 클래스를 훨씬 유연하게 결정할 수 있다. 이 유연성을 활용하면 public으로 선언되지 않은 클래스의 객체를 반환할 수 있기 때문에 구현의 세부사항을 감출 수 있어 간결한 코드가 된다. 예로는 인터페이스 기반 프레임워크 구현이 있다.


네 번째 장점은, 형인자 자료형 객체를 만들 때 편하다.

Map<String, List<Points>> map = new HashMap<String, List<Points>>();

위 처럼 자료형 명세를 중복하면, 형인자가 늘어남에 따라 길고 복잡한 코드가 만들어진다.

하지만 팩토리 메서드를 사용한다면

public static <K, V> HashMap<K, V> newInstance(){
    return new HashMap<K, V>();
}
Map<String, List<Points>> map = HashMap.newInstance();

위 처럼 좀 더 간결하게 작성이 가능하다.

 

팩토리 메서드 이름짓기

현업에서 이름은 보통 다음과 같은 것을 사용한다.

  • valueOf : 형변환 메서드로, 인자로 주어진 값과 같은 값을 갖는 객체를 반환한다는 뜻.
  • of : valueOf 의 축약
  • getInstance : 인자의 값을 갖는 객체를 반환하지만, 인자와 같은 값을 갖지 않을 수도 있다. 싱글턴 패턴을 따르는 경우, 인자 없이 항상 같은 객체를 반환한다.
  • newInstance : getInstance 와 같지만 호출 시마다 다른 객체를 반환한다.
  • getType : getInstance 와 같지만, 반환될 객체의 클래스와 다른 클래스에 팩토리 메서드가 있을 때 사용한다. Type은 팩토리 메서드가 반환할 객체의 자료형이다.
  • newType : newInstance와 같지만, 반환될 객체의 클래스와 다른 클래스에 팩토리 메서드가 있을 때 사용한다. Type은 팩토리 메서드가 반환할 객체의 자료형이다.

 

나는 팩토리 메서드의 존재 조차 모르고 살다가 코드스쿼드 에 와서 Pobi 에게 배우면서 알게 되었는데, 처음에는 생소해서 위 질문처럼 의문점을 가졌었는데 직접 써보다 보니까 점점 팩토리 메서드의 진가를 알게 되는 것 같다.

팩토리 메서드는 보통 생성자가 2개 이상인 경우에 많이 사용하고, 의도를 구분해주는 역할로 사용한다.

이외에 팩토리 클래스도 있는데, 팩토리 클래스는 내가 아닌 다른 클래스 인스턴스를 생성해주는 로직을 가지는 클래스를 말하며, 인스턴스 생성하는 로직이 복잡한 경우에 사용한다.

예를 들면 좌표를 입력받아 좌표의 개수에 따라서 삼각형 또는, 사각형의 넓이를 구하는 좌표 계산기 프로그램을 만들 때, 팩토리 클래스를 이용해서 구현할 수 있다.

ex) Triangle 클래스, TriangleFactory 클래스 (Triangle 객체를 생성하는 팩토리 메서드를 담고있다.)


=-------------------------------------------------------------------------


DTO

데이터 전송 객체(Data transfer object)


보호막을 씌운ㄷㅏ


domain 에서 

Schedule클래스에서 똑같이 복사한 ScheduleDto 클래스를 만든다


(값 도출하는 메소드들은 제외하고 생성자, 게터, 세터들만 남겨둔다)


domain 에서 Schedule클래스에서 다음과 같이 Dto객체 생성 메소드를 작성한다.

public ScheduleDto SchdeduleDto() {
return new ScheduleDto(this.date, this.contents);
}


로직진행은 전부 동일하게 하다가, 이제 값이 변경될 상황이 없으면 dto 객체를 생성해주고 resultview같은 곳에 dto를 넘겨준다. 그러면 진짜 값은 보호되는 안전한 상황. 다만 이후 값이 변경된다면 다시 dto를 선언하던가 해야겠지... 그러니 값이 변경되지않을때 되서 선언하던가 하자.


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
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 27 28
29 30 31
글 보관함