애플리케이션 개발은 어떤 순서로 하면 좋을까?

2012-11-01 21:24

Business Layer에 Interface를 만들어야 할까?(http://www.slipp.net/questions/19)를를) 가지고 논의를 하다가 Interface 우선 설계라는 말이 나오면서 또 다른 궁금증이 생겼다.

Interface 설계를 우선하려면 어떻게 하면 가능할까? 이와 관련해 애플리케이션 개발 순서를 어떻게 하는 것이 좋을까에 대한 궁금증이 일었다. 내가 애플리케이션을 개발하는 순서는 다음과 같다.

먼저 대략적인 도메인을 설계한다. 즉, 대략적인 클래스 구조를 잡는 것이 먼저이다. 클래스 구조를 잡은 후 속성들을 하나씩 채워 나간다. 현재 JPA를 사용하고 있기 때문에 각 속성에 데이터베이스와의 매핑 정보를 추가해야 한다. 하지만 처음 구현할 때는 매핑은 하지 않은 상태로 기본적인 뼈대와 속성 추가에만 집중한다. 만족할만한 수준으로 뼈대가 완성되면 이때부터 데이터베이스에 대한 매핑 정보를 추가하고 Repository를 구현한다. Repository는 Spring Data JPA를 사용하고 있기 때문에 기본적인 CRUD 기능만 가능한 상태로 유지한다.

여기까지 일단락을 지은 후 Controller를 추가하고 JSP를 만들어 기본적인 화면 흐름을 구현하고 확인한다. 이 과정을 마친 후에 Business Layer를 하나씩 추가해 Controller와 Repository를 연결하는 방식을 취한다. 물론 도메인 모델에 대한 속성이나 구조는 기능을 하나씩 구현해 가면서 계속해서 발전해 나간다. 위 시점에 Business Layer의 Interface를 도출하기 가장 좋은 시점은 Controller를 구현한 후 요구사항을 만족하기 위한 Business Layer를 만들어 가능 과정이지 않을까 생각한다. 하지만 이 방법이 적절한지는 모르겠다. 지금까지 특별히 정해진 원칙 없이 내가 필요하다고 생각하는 시점에 하나씩 추가하는 방식을 취했기 때문이다. 그렇다보니 Interface에 메소드를 하나 추가하는 것을 너무 쉽게 생각하는 것이 아닐까라는 의구심이 든다. "Business Layer에 Interface를 만들어야 할까?" 글에서도 언급했지만 Interface와 구현 클래스가 1:1 관계라면 Interface를 만들지 않았다. 특별히 필요성을 느끼지 못했기 때문이다. 그런데 Interface를 만들지 않고 바로 구현 클래스로 넘어가다보니 Interface의 인자와 반환 값에 대해 신경쓰는 시간보다 바로 구현을 고민하는 상황이 되는 것은 아닌가라는 생각도 해본다.

프로그래밍에 정답은 없겠지만 어떤 방식으로 애플리케이션을 개발해 나가는 것이 적합할 것인지 같이 고민해 봤으면 좋겠다.

7개의 의견 from SLiPP

2012-11-02 16:47

일단 이게 주제 자체가 좀 거대한 녀석인데다가... 국내에서는 아무래도 OOP에 대해 이야기가 별로 안나오는 편이라서요... OOP 개념이 들어간 언어를 어떻게 써야 하냐 하는 이야기 정도나 살짝 나오는 수준? 그러다 보니... 내용이 좀 복잡하게 엉켜있어요. Interface 개념이 왜 튀어나왔는지, 다른 언어에서는 Interface 부분을 어떻게 다루는지... 이런 부분들도 있다 보니...

2012-11-03 13:58

음. 일단, 제 의견은 전체적으로 좀 급진적인 방향이라 양해 부탁 드립니다.

저는 이전 댓글에서 명기했던, 행위 그룹 이라는 부분이 핵심이라고 보고 있습니다. 아직 국내에서는, Object/Object Oriented Programming에 대한 이해에 초점을 두고 있는 사람이 많지 않아, Java라는 특정 언어 기준으로 봤을 때 오해가 많이 남아 있다는 느낌을 받고 있습니다.

  1. Object != Structure + Function

술자리에서 몇번 이야기 하지만, 개별 언어는 개별 언어의 사상으로 접근해야 본질적인 영역에 대한 이해가 쉬워집니다. 이 부분은 실제 코딩에서도 적나라하게 나타나고, 업무에서도 일상적으로 "언어만 Java네"라는 표현을 쓰는걸로 확인 할 수 있습니다.

Object는 Structure + Function이 아닙니다. 그건 OOP를 이해하기 쉽게 하기 위해 이미 C를 알고 있는 사람들에게 설명하는 메타포에요. 비유를 공식으로 생각하면 곤란한 문제가 생깁니다.

1:1 기준으로 Interface:Class 를 사용하면 안되는 이유가 이 부분에서 생깁니다. 기존에 C기반의 설계에 익숙하신 분들은 Function Definition 관점에서 Interface를 생각하게 됩니다. (예를 들자면, C의 Header 파일들을 생각하시면 됩니다.) 아래에 좀 더 자세하게 설명하겠지만, Function과 Method는 (유사해 보이지만) 아주 다른 사상을 가지고 있고, 이 부분은 문법적인 영역에서 검증이 불가능한부분입니다. 따라서 코딩 하는 사람이 잘 생각해서 분화시켜야 하는 부분이에요.

  1. OOP 이야기

OOP에서 기본적인 영역이 무엇인지를 바라보는 시각은 여러가지가 있습니다. http://en.wikipedia.org/wiki/Object-oriented_programming 에 나와 있는 몇 가지를 보면 다음과 같습니다. (Fundamental features and concepts 부분)

  • Dynamic Dispatch
  • Encapsulation
  • Subtype polymorphism
  • Object Inheritance
  • Object recursion
  • Classes of objects
  • Instances of classes
  • Methods which act on the attached objects.
  • Message passing
  • Abstraction

익숙하신 부분도 있고, 그렇지 않은 부분도 있으시겠지만, 아무튼 이렇게 다양한 사상/기법/방법들이 OOP를 구성하고 있습니다. 시대에 따라 다르지만, 요즘 OOP에서 강조하는 부분은 Message passing 입니다. Method Call을 Function Call 관점에서 보는 것이 아니라, 특정 Object에 Message를 보낸다는 형태로 보는 관점이죠. 이 관점에서 Interface를 바라보면, 정의되어 있는 Recive Message 에 대한 규칙이에요. 너무나도 당연하게도, 인지하고 있지 않지만 모든 설계는 Interface 설계를 포함하고 있습니다.

  1. Class / Interface

순수한 정의로 돌아가 보죠.

Class에 대해서는 다음과 같이 설명하고 있습니다.

The Java Programming Language, 4th Edition, Chapter 2(P41), First Paragraph THE fundamental programming unit of the Java programming language is the class. Clases provide the structure for objects and the mechanisms to manufacture objects from a class definition. Classes define methods: collections of executable code that are the focus of computation and that manipulate the data stored in objects. Methods provide the behavior of the objects of a class. Although you can compute using only primitive types - integer, floating-point, and so on - almost any interesting program will create and manipulate objects.

Interface에 대해서는 다음과 같이 설명하고 있죠.

The Java Programming Language, 4th Edition, Chapter 4(P117), First Paragraph THE fundamental unit of programming in the Java programming language is the class, but the fundamental unit of object-oriented design is the type. While classes define types, it is very useful and powerful to be able to define a type without defining a class. Interfaces define types in an abstract form as a collection of methods or other types that form the contract for that type. Interfaces contain no implementation and you cannot create instances of an interface. Rather, classes can expand their own types by implementing one or more interfaces. An interface is an expression of pure design, whereas a class is a mix of design and implementation.

위 인용구들에서 잘 알 수 있듯이, Object-Oriented Design에서 기본이 되는 요소는 Type 입니다. Interface에 대한 소개 부분 마지막 줄을 보시면, An interface is an expression of pure design, whereas a class is a mix of design and implementation. 이라고 되어 있는데, 이 부분이 Interface에 대해 거의 모든것을 알려준다고 생각합니다.

마찬가지로, Class를 소개한 문단 바로 다음 문단을 보면 좀 더 명확해 지는 부분이 생깁니다.

The Java Programming Language, 4th Edition, Chapter 2(P41), Second Paragraph Object-oriented programming strictly separates the notion of what is to be done from how it is done. "What" is described as a set of methods (and sometimes publicly available data) and their associated semantics. This combination - methods, data, and semantics - is often described as a contract between the designer of the class and the programmer who uses it because it says what happens when certain methods are invoked on an object. This contract defines a type such that all objects that are instances of that type are known to honor that contract.

Java를 만든사람들이 보기에, Object-oriented Programming 은 "How" 보다는 "What"에 초점을 맞추고 있고, "What"을 나타내는 방법은 set of methods 라고 이야기 하네요. ("What" is described as a set of methods (and sometimes publicly available data) and their associated semantics.) 결국, 전체 개발 과정에서 "What"에 관심을 가지면, Interface 설계는 자동으로 따라오는거라고 봅니다.

  1. 결론

제 기준으로 봤을 때, Interface 설계라는 단계는 따로 존재하는 부분이 아닙니다. Domain 설계와 맞닿아 있는 부분입니다. Domain 설계도 말이 좋아 Domain 설계지, (What) Domain 부분이 생략된 거라고 보는 관점이라, 정상적인 Domain 설계는 Interface 설계를 포함한다고 생각합니다. 다만, Java에서 이야기 하는 Interface 설계를 (좀 더 이상적으로) 하려면, 설계자는 필히 외부 API 설계 경험이 있어야 합니다. 요즘 많이 보이는 REST 기반이라던가, 혹은 RMI나 CORBA 등의 설계를 해보지 않은 상황에서 Java의 Interface 설계를 이야기 하기에는 무리가 있다고 봅니다. 이유는 당연하게도, 최근의 1:1 매칭 Interface Class 관계의 경우에, 손쉽게 Interface 수정이 일어날 수 있다는 점 때문입니다. 외부 API 설계 경험이 있다면, 이 부분이 얼마나 황당한 이야기인지 알 수 있을 겁니다. 코딩하는데 불편하다고 "Facebook API 고쳐주세요!"하면 "있는 걸로 하세요. 다음 버전에는 고려해 볼께요."라는 이야기가 나오는게 정상이지, "고객님 죄송합니다. 바로 고쳐 드릴께요."라고 할 리가 없다고 봅니다. 손쉽게 Interface 변경이 가능하다면, 해당 Interface를 여러 클래스에서 구현하기 힘들어지고(이거 하라고 Interface가 나왔는데도 불구하고요.) 변화가 발생했을 때 어디까지 영향이 가는지 예측이 힘들면 새로 만드는 개발자들의 특성상, 1:1 매칭이라는 결과가 나오는 것으로 봅니다. 굳이 개발 프로세스의 일부분으로 통합해서 강제 한다면, 전 Interface Project를 따로 따고, jar만 배포하는 방향을 추천합니다. 어차피 Interface 부분은 설계하는 사람하고 구현하는 사람이 별도인게 자연스러운 부분이니까요. M:N이 정상인 Interface:Class가, 1:1 혹은 1:N 만으로 나오게 된다면, 다중 구현(Multiple Implementation)을 사용하지 않겠다는 의미가 되는데, 이는 시스템을 복잡하게 만들어 버리는 결과를 가져 옵니다. Class 라는 것 자체가 여러 Interface를 통합해서 다룰 수 있는 구조로 되어 있는데, 이걸 일부러 1:1 혹은 1:N으로 만들어 복잡하게 만드는 거니까요.

2012-11-03 13:59

이전 글에서 이야기 됐던 Interface 설계 라는 부분과, 개발 순서가 어떻게 되어야 하는가 부분에 간극이 있어 논지가 이 질문하고는 좀 벗어난 듯 하네요. 개발 순서에 관한 부분은 따로 정리해 보겠습니다. ㅠ.ㅠ

2012-11-03 17:30

@Kenny 와 장문의 글 좋네. Interface와 OOP에 대해서 다시 한번 고민해 볼 수 있는 글이다. 지금까지 Interface에 대해 대충 감만 잡고 필요한 시점에 사용했는데 기번 기회에 다시 한번 생각을 정리하고 네 글에 질문한 부분이 있거나 공감하지 못하는 부분이 있다면 반박도 한번 해봐야겠다.

최근의 흐름이 Message passing 이라는 것에는 공감한다. 가끔씩은 Message를 전달한다는 개념으로 접근하면 어느 Object에 책임이 있는지를 판단할 때 좋더라고... 어느 Object에 책임을 지우는 것이 결정되면 이 때 하나의 Interface가 추가되면서 업무를 위임할 수 있겠더라고.

의견 추가하기

연관태그

← 목록으로