Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

키스하기()를 포옹하기()로 바꾸는 것이 OCP위반일까요? #14

Open
SoohyeonB opened this issue Jun 15, 2022 · 2 comments

Comments

@SoohyeonB
Copy link
Collaborator

B824099D-56D1-427C-8742-D48839F20610

Untitled
저는 위 코드에서

  1. 클라이언트 코드인 MemberService의 코드를 변경하여 ocp 위반
  2. 남자친구 클래스가 키스하기()메소드를 의존하고 있기 때문에 변경시 클라이언트 코드까지 변경하게 되어 DIP 위반
    이라고 생각했습니다.

https://www.notion.so/5-12-5e7a5e230bf9487f80f547f31a9da974#a2e51f4470aa4e64bd847cbd5ee6b0fd
⬆️ 김영한이사 인프런 강의를 들으며 정리한 내용 링크입니다!

@SoohyeonB
Copy link
Collaborator Author

Untitled (1)
위 코드의 구조는 현재 이렇습니다.

  1. 클래스 안의 메소드를 변경하는 것도 ocp를 위반하는 범위 안에 들어오는가?
    --> 하나의 책임만을 갖고 있고 (남자친구로서의 정체성), 객체를 새로 생성하고 연관관계를 맺어주는 역할도 없기 때문에 ocp 원칙을 지킨다는 생각도 듭니다
  2. 다른 클래스의 메소드를 의존하는 것이 아니기 때문에 dip 위반이 아니라는 생각이 들었습니다!
    어제 말씀해주신대로 본인의 메소드이기 때문에 solid의 원칙에 위배되는 것은 없는 것 같습니다.

@eeHeaven
Copy link
Contributor

eeHeaven commented Jun 16, 2022

OCP의 핵심은 notion에서 정리하신 것과 같이 특정 역할을 구현하는 객체가 여러 개로 확장된 경우입니다!
image
정리된 이미지에서 보시는 바와 같이 운전자(클라이언트) 입장에서 차종이 무엇이든 상관없이 시동을 걸거나, 운전을 하고, 주차를 시키는 행동 등을 해야할 때 OCP 원칙을 따라야 합니다.

클라이언트가 자동차를 운전할 때
운전하기(자동차) 라는 메서드를 사용한다고 가정해봅시다.
클라이언트 입장에서는 자동차 종류에 상관없이 운전이 가능해야 하고 운전은 자동차가 구현객체(차종)에 상관없이 공통적으로 할 수 있는 기능입니다.
자동차자리에 자동차 인터페이스를 구현한 K3, 아반떼, 테슬라 객체가 들어가도 그들이 공통적으로 실행하는 운전하기 기능은 여전히 잘 수행되어야 하며 이는 리스코프 치환 원칙을 지키는 사례이기도 합니다.

제시해주신 키스하기 -> 포옹하기 메서드 변경은 상황에 따라 OCP를 위반한 것일 수도, 아닐 수도 있습니다.

OCP의 핵심은 애초에 기능이 확장될 수 있는 문제는 미리 인터페이스로 만들어놓자입니다.
예를 들어 원래는 세상에 차종이 K3밖에 없어서 시동을 걸면 "K3입니다" 라는 문구만 떴었는데 미래에 다른 차종이 생길 수도 있고 그에 따라 시동을 걸었을 때 다른 메세지를 띄울 수 도 있는 경우에는 미리 자동차 인터페이스를 만들어 놓자는 겁니다.

같은 원리로 남자친구 예시도 조금은 억지스럽지만 만약 지금은 키스하기만! 하는 남자친구만 사귀려고 했는데
미래에 다른 손잡는 남자, 포옹하는 남자를 만날 수도 있다면
클라이언트 입장에서 해당 내용을 스킨십하기(남자친구)로 메서드 구현을 할 것이고
그에 따라 남자친구는 SRP에서는 하위 클래스로 나뉘어졌지만 이 경우에는 인터페이스로 구현이 되어야 합니다.
그리고 해당 인터페이스를 구현하려면 스킨십() 메서드가 있어야하고 각 키스하는,포옹하는, 손잡는 남자친구 클래스가 남자친구 인터페이스를 구현받아 각자 자기 스킨십을 구현하면 됩니다.
그러면 클라이언트는 어떤 남자친구 구현체를 만나든 스킨십하기(남자친구) 메서드는 변경 안해도 되는 거죠!

그런데 만약 위와 같이 스킨십의 종류가 다양해진 경우가 아니라
영구적으로 키스하기를 아예 안써버리고 그걸 모두 포옹하기로 대체하겠다고 하는 경우(그리고 앞으로 스킨십 기능 확장이 위의 상황처럼 발생할 가능성이 없는 경우)는 상황이 달라집니다.
이럴 경우 OCP의 원칙과는 무관하며 어쩔 수 없이 남자친구 클래스의 메서드를 키스에서 포옹으로 변경할 수밖에 없으며
클라이언트 코드도 그에 따라 불가피하게 변경됩니다.
이런 상황은 최대한 지양하는 것이 맞지만 기능 확장을 핵심으로 하는 OCP의 취지와는 무관하기 때문에 OCP가 위배되었다고는 할 수 없습니다.
그러나 지양해야 하는 상황은 맞을 겁니당,,, 이펙티브 자바에서 그래서 public 클래스를 구현할 때는 이미 외부 사용자가 해당 클래스를 사용하기 때문에 변경이 무진장 어려워서 신중에 신중에 신중하라고 엄청 강조하고 웬만하면 애초에 public 접근 제어자로 클래스를 만들지 말라고 하기도 한 것 같아요

말이 길어졌는데 아무튼 제가 이해한 바로는 OCP는 클라이언트가 이것도 써도 되고 저것도 써도 되는 상황을 만들자는 거라 단순히 클라이언트의 코드가 변경될 수 있다는 것만으로 OCP가 위반됐다고 할 수는 없는 것 같아요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants