[완료] SRP vs ISP 에 대해..

GMRyuj의 이미지

안녕하세요. 요세 한창 소프트웨어 설계를 공부하고 있는 현역군인입니다.

설계를 공부하던 도중 SRP 와 ISP 원칙이 서로 의미가 다른 것 같아 질문드립니다.

SRP는 단일 책임의 원칙으로써 클래스는 하나의 책임만을 가지는 것이고..

ISP는 인터페이스 격리의 원칙으로써 클래스는 자신과 관계없는 메소드나 기능을 인터페이스로 분리시키는 원칙이라고 배웠습니다.

여기서 약간의 모순점(?) 이라고 해야하나.. 뭔가 느낌이 모순된 느낌입니다.

SRP는 분명 단일 책임을 가져야하는 것이고.. ISP는 분명히 사용하지 않는 메소드나 기능을 분리하여 인터페이스로 분리하는 원칙인데..

ISP로 나뉘어진 인터페이스를 복수개로 상속받아 구현하게 된 클래스가 있다면.. 복수개의 책임을 가지게 되지 않습니까? (이건 분명 SRP 원칙에 어긋납니다.)

예를 들면 어떤 한 게임 객체가 있는데 이 객체는 Update 와 Draw 라는 메소드의 기능이 있습니다.

이 게임 객체는 IDrawable 인터페이스와 IUpdateable 인터페이스를 구현하게 됩니다.

그럼 게임객체는 그려질 책임과 업데이트를 할 책임을 가지고 있게됩니다. (아니면 객체를 구동시키는 책임을 클래스가 새로이가지게 되는 것입니까...? )

이것은 분명 SRP 원칙의 위반인데..

저가 공부를 잘못해서 그러는건지.. 아니면 이게 맞는 건지 잘 모르겠습니다. 경험 많으신 분들의 답을 기다려봅니다..

익명 사용자의 이미지

두 책임을 합쳐서 더 큰 하나의 책임으로 추상화될 수 있어야겠지요.

chadr의 이미지

일단 인터페이스라는 것에 대해서 정확한 정의가 필요할 것 같습니다.
여기서 인터페이스는 두개의 의미를 가집니다.

1. C++에서 순수가상함수, Java와 같은 언어에서의 interface 키워드를 이용해서 만들어진 클래스
2. 외부와 데이터를 주고 받기 위해서 만들어진 일반적인 함수. get/set를 말합니다. 이런 함수는 기능적인 면보다는 기능을 수행하기 위해 외부와 상호작용(인터페이스)을 하기 위한 함수들입니다.

만약에 여기서 인터페이스가 1번을 의미하는 것이라면 모순이 됩니다.
하지만 인터페이스가 2번을 의미하는 것이라면 모순이 아닙니다.

하지만 1번이더라도 다르게 생각해보면 모순이 아닐수도 있는게..
인터페이스지만 실제로는 인터페이스를 가지는 클래스는 해당 인터페이스를 수행할 책임이 없습니다.
인터페이스를 이용해서 구현 된것은 자식 클래스일테니까요. 이렇게 되면 외부에서 볼때 부모 클래스는 감춰지게되고 실제로 겉으로 보이는 것은 인터페이스를 구현해서 수행하는 자식 클래스이게 욉니다. 이렇게 해석이 된다면 모순이 아닙니다.

어떻게 해석을 하냐에 따라서 모순여부가 달라질 것 같습니다.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

익명 사용자의 이미지

좋은 설계는 도메인 영역에 대한 빠삭한 이해로부터 나온다고 봅니다. 만들어야 할 소프트웨어의 필수 구성물들이 서로 어떻게 연결되는지 큰 그림이 머리 속에 이미 그려져 있고, 각 연결부에서 예상되는 병목과 그 병목을 해소하기 위한 가장 효율적인 방법이 무엇이냐를 묻는데서부터 설계가 시작됩니다.

미시적으로 IDrawable이니 하는 것들은, 그런 큰 그림에 따라 이미 처음부터 대강의 정답을 알고 있어야 하는 겁니다. 가령 이 인터페이스를 통해 vertex나 텍스쳐 데이터를 주고 받게 할 것인지, 아니면 적당한 핸들만 주고 받게 할 것인지는 중간에 캐시를 쓸 것이냐 말 것이냐에 따라 사실상 자명해지는거죠. 기타 잡다한 거야 나중 나중 아주 나중에 refine할 일이고요.

그런데 필요한 도메인 지식을 갖고 있지 못한 상태에서 인터페이스를 설계하려고 해봐야, 픽셀 하나 하나 찍는 인터페이스 만들어 놓고 separation of concern이 잘 된 설계라는 둥 하면서 자뻑에 빠지기는 얼마나 쉽나요. 실시간 통신이 필요한데, 동기식 API 위에 공들여 인터페이스 만들어놓아봤자 실제 돌려보면 느려 터져서 그 코드 몽땅 버려야 되죠. 허공에다 집짓는 겁니다.

개인적으로, 저런 종류의 개념들을 "소프트웨어 설계"라고 통칭해서 부르는게 매우 못마땅합니다. 웹서비스처럼 추상 수위가 아주 아주 높은 종류의 특수한 도메인에서나 정당화될 수 있는 말이고, SI를 할 거라면 매우 중요하겠지만, 다른 영역에서는 완전히 다른 종류의 관점이 훨씬 더 중요합니다.

익명 사용자의 이미지

SI에서도, DB에 대한 이해 없이 지 멋대로 "객체지향적"으로 설계해놓으면.. ㄷㄷㄷ

GMRyuj의 이미지

익명사용자님께서 달아주신 답글에 100% 공감합니다. 정말루 설계를 하기전에 내가 전에 게임을 만들때 생겼던 문제점들, 반드시필요했던것들에 대한 이해가 있어야 좋은 설계가 나온다고 봅니다.

좋은 답글 정말 감사드립니다.!

이 세상에서 불가능한 것은 단 하나뿐이다.
그것은 자신을 완벽히 믿는 것이다.

익명 사용자의 이미지

사실 구루라는게 이런 거 아닌가 싶어요. 적어도 그 도메인에 속하는 어플리케이션의 지도를 딱 펼쳐놓고선, 어느 곳이나 손가락으로 짚으면서 이 컴포넌트에는 더도 덜도 말고 딱 이 기능만 있으면 돼, 얘랑 얘는 붙어있는게 아니라 나뉘어야 돼, 여기서 여기로는 이렇게 데이터를 주고 받아야 돼. 라고 말할 수 있는 경지요. 그리고 그건 서로 상충하기 일쑤인 추상적 원칙들에 의해서가 아니라, 구체적이고 실물적인 근거에 의해서겠죠.

아마도 소프트웨어 설계의 여러가지 원칙들, 패턴들이라는 것도 그런 것들을 추상화해서 정리한 것일텐데, 거꾸로 추상적인 원칙들만 갖고 설계하려 들면 길을 잃을 수 밖에 없겠죠. 어떤 경우에 어떤 패턴을 적용해야 하는지 모르니까. 만고 쓸데 없는 데는 오버엔지니어링이 난무하는데, 정작 꼭 필요한 곳은 엉터리로 되어있다던지. 뭐 그런.

GMRyuj의 이미지

맞는 것같습니다. 그래서 경험있는 사람이 설계를 하는 것 같습니다. 소중한 답글 감사드립니다!

이 세상에서 불가능한 것은 단 하나뿐이다.
그것은 자신을 완벽히 믿는 것이다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.