- 디자인은 무엇이고, 왜 필요하고. 어떻게 하는 것인지 + 객체지향은 무엇인지
- 객체지향 디자인에 대한 일반적인 논의에서 시작하여, 객체지향 디자인이 왜 필요한지, 언제 디자인을 적용할지 그리고 어떻게 판단할지 설명
디자인
디자인은 무엇인가
- 디자인은 코드를 배치하는 것
-
디자인의 어려움 중 하나는 모든 문제가 두 부분으로 구성되어 있다는 점
- 오늘 완성해야 하는 기능을 구현하는 코드를 짜야하고,
- 동시에 내일 쉽게 바꿀 수 있는 코드를 짜야한다.
- 실용적 디자인은 우리의 애플리케이션에 어떤 일이 벌어질지 예측하는 것이 아니라, 단지 언제가 무엇가는 변한다는 사실, 그리고 지금은 무엇이 변경될지 알 수 없다는 사실을 받아들이는 것이다.
-
디자인의 목표
- 디자인은 나중에 디자인할 수 있는 여비를 남겨 놓기 위한 것이고, 그 최종 목표는 변화의 비용을 최소화하는 것이다.
디자인은 왜 필요한가?
- 아무것도 변하지 않는다면 디자인은 필요하지 않다.
-
불행히도 무언가는 항상 변한다.
- 고객은 자신이 무엇을 원하는지 몰랐고, 고객이 했던 말은 실제 말하고자 했던 바가 아니었다.
- 변화는 어디에나 있고 모든 곳에 있으며 피할 수 없다.
- 변화가 필요하기 때문에 디자인이 중요하다.
-
변화를 주기 힘든 애플리케이션
- 수정을 하려면 많은 시간이 필요하다.
- 하나를 수정하면 다음번 수정이 더욱 어려워진다.
수정이 어려운 이유
-
객체지향 애플리케이션은 상호작용하는 여러 부분으로 구성되어 있고, 각 부분 사이의 상호작용이 전체의 작동을 만들어 낸다.
- 객체 사이의 상호작용은 의존성을 만들어 낸다.
- 의존성 때문에 하나의 객체가 수정되었을 때 상호작용하고 있는 다른 객체까지 변경이 전파될 수 있기 때문에 수정이 어려워 진다.
-
하나의 객체가 너무 많은 기능을 담당할 경우 변화에 대응하기 어렵게 된다.
- 새로운 맥락 속에서 다시 사용하기 어렵고
- 테스트 하기 어렵고
- 중복되기도 쉽다.
-
수정이 쉬운 객체를 만들기 위해서 자율적인 객체를 만들어야 한다.
-
자율적인 객체 = 다른 객체로부터 온 요청을 어떻게 처리할지 스스로 결정하는 객체
- 객체는 다른 객체에게 요청할 때 무엇을 해야하는지만 요청하고 어떻게 동작해야 하는지에 대해서는 요청하지 않는다.
- 어떻게 동작할지는 요청을 받은 객체가 스스로 결정한다.
- 객체가 자율적이기 위해서는 하나의 책임만을 수행할만큼 작고 어떻게 행동할지 판단할 수 있도록 하는 충분한 데이터가 있어야 한다.
-
-
가끔은 지금 당장 기능을 구현하는 것이 너무나 중요해서 미래의 수정비용이 높아 지는 것을 감내해야 할 때가 있다.
- 이와 같은 방식으로 타엽하는 것은 미래의 시간을 빌려오는 것과 같다. 기술적으로 빚을 지는 것이다.
-
우리의 목표는 기능별 구현 비용이 가장 낮은 소프트웨어를 개발하는 것이기 때문에, 디자인에 얼마나 시간과 돈을 쓸지 결정하기 위해서는 두 가지를 고려해야 한다.
- 우리의 기술 수준
- 우리에게 주어진 시간
- 디자인 비용의 손익분기점은 프로그래머마다 다 다르다. 열심히 잘 공부하자.
디자인은 어떻게 하는가
- 객체지향 디자인은 의존성을 관리하는 것이고, 객체가 변화를 받아들일 수 있도록 의존성을 정리하는 코딩 기술의 묶음.
- 디자인은 지금의 선택이 다음 선택지를 제한하고 또한 새로운 선택지를 열어주는, 그런 갈림길을 따라가는 여행이다.
-
객체지향 디자인에는 원칙과 패턴이 있다.
-
원칙
- SOLID - 단일책임, 개방-폐쇄, 리스코프 치환, 인터페이스 분리, 의존성 역전
- DRY - Don't Repeat Yourself
- 데메테르 원칙
-
패턴 - gof
- 패턴이란 객체지향 소프트웨어 디자인에서 명확한 문제를 처리하는 간단하고도 우아한 해결책
- 패턴을 이용하면 우리의 디자인을 보다 유연하며 이해하기 쉽게 만들 수 있으며 모듈화하여 재사용할 수 있게 만들 수 있다는 것
- 패턴을 잘못 적용하면 복잡하고 혼란스런 코드를 낳게 된다.
-
디자인의 실패
-
소프트웨어 디자인이 실패하는 이유
-
디자인 자체가 부족함
-
디자인이 없는 애플리케이션은 그 자체로 붕괴의 씨앗을 품고 있다.
응, 그 기능 추가할 수 있어. 대신 다른 기능은 다 고장날거야 - 9p
-
-
디자인 기술에 대해 알고 있지만, 이 기술을 어떻게 적용해야 하는지 잘 알지 못함
- 좋은 의도로 지나치게 디자인하는 함정에 빠진다.
-
약간의 지식을 함부로 사용하는 것은 위험한 일이다.
아니, 새로운 기능을 추가할 수 없어. 처음부터 그렇게 디자인되지 않았다고. - 9p
-
디자인 작업과 프로그래밍 작업이 동떨어져 있을 때
- 디자인은 반복적인 되먹임과 함께하는 점전적인 발견의 과정
- 때문에 반복을 중시하는 애자일 소프트웨어 개발 운동은 잘 디자인된 애플리케이션을 만드는 데 매우 적합하다.
- 애자일 개발의 반복적인 특징은 디자인이 지속적인 자기조절 능력을 갖추고, 자연스럽게 발견할 수 있게 도와준다.
-
언제 디자인을 해야 하는가
-
커다란 디자인을 먼저 구상하는 방식은 결국 고객과 프로그래머를 서로 대립하게 만든다.
-
커다란 디자인을 먼저 구상하는 방식
- 주어진 애플리케이션의 모든 기능과 내부 작동 방식의 미래를 예상하고 그 내용을 완벽하게 명시하고 전체를 문서화 하려는 시도
- 객체지행 디자인은 훨씬 좁은 영역에만 관심을 갖는다. -> 코드를 손쉽게 수정하려면 코드를 어떻게 배치해야 하는가
-
- 고객들은 개발이 완료된 애플리케이션을 사용 하려는 순간에 가서야 원하는 것을 충족시켜 주지 못한다는 것을 알게된다.
-
애자일은 애플리케이션이 존재하기 전에 확실한 것은 없다는 사실을 받아들인다. -> 애자일 작업방식은 변화를 보장한다.
- 애자일은 디자인을 거부하지 않는다. 진짜 좋은 디자인을 필요로 한다.
객체지향
절차지향과 객체지향
-
절차지향
- 프로시저의 호출 개념을 바탕으로 하는 프로그래밍 패러다임
-
절차지향과 객체지향의 큰 차이점은 데이터와 프로시저(행동)을 별개로 취급한다는 것
- 때문에 절차적 프로그램에서 하나의 데이터를 어떤 프로시저에서든지 수정하고 사용할 수 있다.
- 이는 데이터가 어떻게 변하고 사용되는지 추적하기 어렵게 만든다. 어떻게 사용될지 예측할 수도 없게 된다.
-
객체지향
- 객체지향 애플리케이션은 객체와 객체가 서로 주고 받는 메시지로 구성되어 있다.
- 절차지향과 다르게 데이터와 데이터를 처리하는 행동을 별개로 취급하지 않고 객체안에 통합
- 객체 안에 있는 데이터는 객체에 있는 행동만이 수정하고 사용할 수 있다.
-
절차지향에 비해 데이터가 어떻게 변하고 사용되는지 추적이 용이함.