인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

꼬꼬록님의 프로필 이미지

작성한 질문수

오브젝트 - 기초편

4-2. 설계 트레이드오프 - 창조자와 낮은 결합도

객체의 생성책임을 객체의 개념 자체에 부여하는 경우에 대한 의견이 궁금합니다.

해결된 질문

작성

·

149

·

수정됨

1

안녕하세요.

 

코드레벨에서의 관점이 될수도 있겠지만, 객체의 생성책임을 자신의 클래스객체에 부여하는 선택지에 대한 고견이 궁금합니다.

저의 경우 기존처럼 설계없이 습관적으로 코드를 짰다면, ReservationService에서 Reservation.with(screening, user, amount)로 생성하고 저장하는 형태로 작성했을것 같다는 생각이 들었고, 이게 수업에서 말씀하신 설계관점에서 생성책임부여 대상으로 괜찮은 것인지 고민이 들었습니다.

제가 고려해보았을때, class객체를 예매 개념 이라고 명명하고 예매 개념이 객체의 생성책임을 부여하기 적절한 객체인지 판단해보자면,

  • 예매를 생성과 관련하여 가장 잘 알고있을것으로 생각되는 정보전문가로 보입니다.

  • 기록하거나 긴밀하게 사용하는 창조자패턴에 가장 부합하는 대상으로 보입니다.

  • 식별된 도메인모델을 기준으로 했을때는 '개념'이라는 객체가 새로 등장하게 되니 표현적차이는 상영보다는 다소 거리가 있어보이지만, 코드레벨에서 예매를 생성하라는 문맥에서 예매 class를 찾으면 되니 표현적차이를 줄임으로써 얻는 변경용이성은 해결되는것이 아닌가 생각했습니다.

  • 협력의 문맥을 책임으로 옮기고 적절한 객체를 식별한다고 할때 예매 개념 을 떠올리는건 뭔가 자연스럽지 않아보이긴 합니다.

이런 판단으로 저는 예매 개념에 생성책임을 부여할것으로 판단했습니다.

여기서 간과한 부분이 있거나 안티패턴은 아닌지 궁금합니다.

설계가 정해진 답이있지 않고, 고차원적인 부분이다보니 판단에 대한 피드백을 받아보고싶었습니다.

답변 2

1

조영호님의 프로필 이미지
조영호
지식공유자

꼬고록님 안녕하세요.

좋은 질문 남겨 주셔서 감사합니다. 🙂

 

클래스에 정적 메서드를 추가해서 객체를 생성하는 것은 정적 팩터리 메서드 또는 생성 메서드라도 부릅니다.

생성 메서드의 역할은 생성자와 동일하게 해당 객체를 생성하는 것이지만, 메서드의 이름을 통해 좀 더 표현력있게 만들 수 있다는 장점이 있습니다.

질문에서 Reservation.with(screening, user, amount)라는 생성 메서드 호출 구문은 아마도 내부에서 new Reservation(screening, user, amount)과 같은 생성자를 호출하기 때문에 역할 측면에서 보면 생성자와 동일하다고 할 수 있습니다.

 

반면에 GRASP 패턴에서 말하는 CREATOR 패턴은 어떤 객체가 Reservation.with(screening, user, amount)나 new Reservation(screening, user, amount)를 호출할 것인지를 결정하는 것입니다.

질문에서 보면 ReservationService가 이 메서드를 호출해서 Reservation 인스턴스를 생성한다고 언급하셨기 때문에, Reservation 객체를 생성할 책임을 Reservation이 아니라 ReservationService에게 할당한 것이죠.

 

모든 클래스는 객체의 메모리를 할당하고 값을 초기화하기 위해 생성자를 정의합니다.

인스턴스를 생성하기 위해 생성자를 추가하거나 내부에서 생성자를 호출하는 생성 메서드를 추가하는것은 객체가 자기 자신을 스스로 초기화하도록 만드는 것일 뿐, 객체를 생성하게 만드는 것은 아닙니다.

객체가 초기화되기 위해서는 누군가 생성자나 생성 메서드를 호출해줘야 하죠.

CREATOR 패턴에서 말하는 생성 책임은 이렇게 어떤 객체가 그 객체가 생성되도록 생성자나 생성 메서드를 호출할 것인지를 결정하는 것이라고 생각하시면 됩니다.

 

답변이 됐는지 모르겠네요.

감사합니다. 🙂

꼬꼬록님의 프로필 이미지
꼬꼬록
질문자

kotlin에서 정적팩토리메서드를 companion object에 정의하다보니, 클래스도 일종의 객체로 볼수 있겠구나 어림짐작했던 부분이 이런방식으로 사고를 이끌어 왔네요.
ReservationService를 Controller패턴을 적용하는 Service Layer로 생각하고, Reservation개념에게 생성책임을 담당하는 후보객체가 될수있다고 판단했습니다.
따라서, 정적팩토리 메서드 내부에서도 단순한 생성자의 역할 보다는 Screening과 협력하면서, 그 이후에 생성자를 호출하여 객체를 생성할 수 있기 때문에, 객체를 생성하는 책임을 부여할 수 있지 않나 고려했습니다. (이경우, 이름이 생성호출수준의 with인건 부적절하네요)

말씀해주신 답변으로 비추어 볼때, 정적팩토리메서드에 책임을 부여하는 사고방식이 통용되는 방식은 아닌것 같고 제가 오개념을 갖고있는것들을 다시한번 되짚어 봐야겠습니다.

 

늘 정성스러운 답변 감사드립니다.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다.

꼬꼬록님께서 제기하신 객체의 생성책임에 관한 질문은 객체지향 설계의 핵심적인 부분 중 하나입니다. 객체의 생성 책임을 어떤 객체가 가져야 하는지는 응집력(cohesion)과 책임(responsibility)의 원칙에 따라 신중히 고려해야 합니다. 이와 관련하여 몇 가지 관점을 제시하겠습니다.

객체 생성 책임의 부여

  1. 정보 전문가(Information Expert) 패턴:

    • 객체를 생성하는 데 필요한 주요 정보를 알고 있는 객체가 생성 책임을 지는 것이 가장 이상적입니다. 클래스가 생성에 필요한 모든 정보를 가지고 있다면 해당 클래스에서 생성하는 방식이 자주 사용됩니다.
  2. 창조자(Creator) 패턴:

    • 생성하려는 객체와 깊은 연관이 있는 클래스가 창조자 책임을 지는 것이 자연스럽습니다. 예를 들어, Reservation 객체를 생성하는데 ReservationService가 아닌 Reservation 클래스 자체가 생성 책임을 맡는 방식이라면, 이는 생성과 밀접한 관련이 있는 경우 효과적입니다.
  3. 도메인 개념과 표현의 일치:

    • 도메인에 대한 명확한 이해가 필요합니다. 도메인 모델에서의 개념과 코드 레벨에서의 표현이 맞아떨어지는지, 해당 추상화가 적절한지를 판단해야 합니다. 주어진 시나리오에서 Reservation이 도메인 개념에 잘 부합하는 경우가 아니라면, 이는 오해를 불러일으킬 수 있습니다.
  4. 유지보수와 확장성:

    • 코드의 변경 용이성을 고려해야 합니다. 객체의 생성 책임을 올바른 곳에 부여하는 것은 향후 유지보수와 확장성에 큰 영향을 미칩니다. 예를 들어, Reservation 생성과 관련된 변경이 발생할 때, 이 변경이 Reservation 클래스 내부에서 충분히 수용 가능한지 살펴봐야 합니다.

위의 패턴은 객체지향 설계 원칙에 기반한 방법으로, 설계는 프로젝트의 구체적인 요구사항과 도메인에 따라 유동적일 수 있다는 점을 인지해야 합니다. 설계에서 정답은 없기에 다양한 시각에서의 접근이 필요합니다.

유사한 주제를 다룬 객체 생성 책임에 대한 질문과 답변 도 참고하시면, 추가적인 통찰을 얻을 수 있을 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.