목록CS 지식/객체지향 (22)
Taking baby-developer steps
객체 지향의 확장 가능하고 재사용성 높은 협력은 다형성 덕이지만, 다형성을 지탱하는 메시지가 존재하기 때문에 가능한 일 이다. 메시지, 객체지향 설계의 중심 객체 지향 애플리케이션의 중심 사상은 연쇄적으로 메시지를 전송하고 수신하는 객체들 사이의 협력 관계를 기반으로 사용자에게 유용한 기능을 제공하는 것이다. 객체 지향 설계는 시스템을 메시지를 주고 받는 동적인 객체들의 집합으로 바라봐야한다.(정적인 클래스들의 집합이 아니다!) 설계 과정에서, 객체들이 주고받는 메시지가 객체들의 윤곽을 결정하게 해야한다. cf > 데이터-주도 설계 메시지가 아닌, 데이터를 중심으로 설계하는 방식. 객체의 내부 구조를 객체 정의의 일부로 만들어 객체의 자율성을 저해한다. 외부에서 객체의 내부 구조 변경까지 관여하기에 객체..
디자인 패턴 공부를 시작하며 이전에 refactoring guru로 디자인 패턴을 공부한 적이 있었다. 귀여운 그림들이 있고 설명이 자세해서 좋은 자료이지만, 사실 그때 나는 클래스와 객체를 동일한 것이라 생각하고 있었기에 디자인 패턴에 대한 근본적인 이해 조차 부족해 제대로 학습하지 못했던것 같다. https://refactoring.guru/design-patterns Design Patterns Design Patterns Design patterns are typical solutions to common problems in software design. Each pattern is like a blueprint that you can customize to solve a particular d..
메서드 객체가 수신한 요청을 처리하기 위해 내부적으로 선택하는 방법을 "메서드"라고한다. 수신한 메시지를 처리할 수 있는지 여부를 확인 한 객체가, 책임을 다하기 위해 메서드를 선택한다. 객체지향 프로그래밍 언어에서 메서드는, 클래스 내 포함된 함수 또는 프로시저를 통해 구현된다. 절차적언어(예를 들어 C)는 프로시저 호출에 대한 실행 코드를 컴파일 시간에 결정하지만, 객체지향 프로그래밍 언어는 그렇지 않다. 다형성 서로 다른 유형의 객체가 동일한 메시지에 대해 서로 다르게 반응하는 것을 의미한다. 메시지는 "무엇"이 실행될지는 명시하지만 "어떻게"실행 할지는 수신자가 결정한다. 즉 동일한 메시지도 서로 다른 방식의 메서드를 이용해 처리할 수 있다. 서로 다른 객체들이 다형성을 만족 시킨다는 것은, 그들..
메시지 - 이번 포스팅은 C++, 자바, C# 등의 언어에서 사용되는 메시지 전송 문법을 사용해 예시를 보인다. 중요한 것은 메시지 전송 문법이 아니라, 메시지 전송을 구성하는 요소이다. 커피 주문을 위한 협력을 떠올려보자. 캐셔가 바리스타에게 "커피를 만들어라"라는 메시지를 전송한다. "커피를 만들어라" 부분을 메시지 이름(message name)이라고 한다. 메시지 전송 시 추가적인 정보가 필요한 경우 메시지의 인자(argument)를 통해 추가 정보를 제공할 수 있다. 커피를 만들어라(카페라떼, 한잔) 메시지 전송은 수신자와 메시지(메시지 이름 + 인자)의 조합이다. 캐셔가 바리스타에게 요청을 하기 위해서는 누구에게 전송을 해야하는지 알아야한다. 바리스타 역할을 맡은 박고슴씨에게 전송하고 싶다면 다..
"명확하게 정의된 역할과 책임을 지닌 객체들을 상호 협력하게 하라" 자율적인 객체 -> 책임의 수준 역시 자율적 스스로의 의지와 판단에 따라 각자 맡은 책임(요청을 처리하기 위해 객체가 수행하는 행동)을 수행하는 객체를 자율적인 객체라 한다. 객체가 자율적이기 위해서는 객체에게 할당되는 책임의 수준 역시 자율적이어야한다. 예를 들어, 앞서 커피 주문에 협력하는 예시에서, 커피를 만드는 역할을 바리스타 객체의 경우 "카페라떼 한잔"을 요청 받았을 때, "에티오피아 원두 30g을 갈아라" "원두에서 2개의 샷을 추출해라" "90도씨로 우유 200ml을 2분간 스팀하라"라는 요청을 받았을 때 보다 커피 제작 방식을 자율적으로 선택할 수 있다. 너무 추상적인 책임 그러나 과도하게 포괄적이고 추상적인 책임 역시 ..
역할, 책임, 협력의 관점에서 애플리케이션을 설계하는 3가지의 유용한 기법이 있다. 책임-주도 설계 -> 객체의 역할, 책임, 협력을 고안하기 위한 방법과 절차를 제시 디자인 패턴 -> 책임-주도 설계의 결과를 표현 테스트-주도 개발 -> 설계를 테스트하는 좋은 도구 책임-주도 설계 - 협력에 필요한 책임들을 식별하고 적합한 객체에게 책임을 할당하는 방식으로 애플리케이션을 설계 객체지향 시스템의 목적은 1. 사용자의 요구를 만족 시킬 수 있는 기능을 제공하고 2. 이해하기 쉽고, 단순, 유연한 상호작용을 제공하는 객체들의 공동체를 구축 하는 것이다. 가장 핵심은 역시나 "올바른 책임"을 "올바른 객체"에게 할당하는 것이다. 객체지향 언어 사용, UML 같은 모델링 언어로 설계의 밑그림을 그리는 것이 객체..
객체 지향 입문자들은 데이터나 클래스를 중심으로 애플리케이션을 설계한다. 이는 협력이라는 문맥을 고려하지 않고 각 객체를 독립적으로 생각하기 때문이다. 그러나 다음을 명심해야한다. 객체가 존재하는 이유는 행동을 통해 협력에 참여하기 위함이다. 객체에서 중요한 것은 데이터보단 객체의 행동, 즉 책임이다. 객체지향은 클래스를 어떻게 구현할 것인가가 핵심이 아니다. 중요한 것은 객체가 협력 안에서 어떤 책임과 역할을 수행할 것인지를 결정하는 것이다. 잘못된 객체지향설계의 예를 살펴보자. "토끼"의 인스턴스 모델링을 할 때 흰털에 빨간 눈, 귀여운 자태를 생각하고 그 모습을 기반으로 클래스를 개발 했다. 그러나 이 전형적인 토끼의 모습으로 소프트웨어 객체를 창조하는 것은 도움이 되지 않는다. "토끼"가 참여할 ..
역할(role)이 왜 필요할까 협력 안에서 어떤 객체가 "수행하는 책임의 집합"은 "수행하는 역할"을 의미한다. 역할과 객체 자체는 어떻게 다를까? 역할은 재사용성을 높이고 유연한 객체지향 설계를 돕는다. 맨 처음 손님이 카페에서 커피를 주문하는 협력과정을 다시 떠올려보자. 손님이 캐셔에게 음료 주문을 요청하고, 캐셔가 바리스타에게 음료 제조 요청을 보낸다. 바리스타는 음료를 제조함으로써 캐셔의 요청에 응답하고, 캐셔는 손님에게 음료가 완성되었음을 알림으로서 응답한다. 이때, 손님이 김철수일 때와 Elin일 때, 캐셔가 박고슴일때와 Nate일 때 이 협력의 과정이 다르지 않다. 모두 "캐셔", "바리스타", "손님"이라는 역할을 할 수 있다면 해당 자리를 어떤 객체라도 대신할 수 있다. 이는 협력을 추상..
객체가 요청에 대해 대답해 줄 수 있거나, 적절한 행동을 할 의무가 있는 경우, 해당 객체는 책임을 가진다. 책임을 객체에 잘 할당하는 것은 객체지향 설계에서 중요하다. 책임 객체에 의해 정의되는 응집도 있는 행위의 집합이다. 객체의 책임은 "객체가 무엇을 알고 있는가(knowing)"와 무엇을 할 수 있는가(doing)"로 구성된다. 각 객체가 명확한 책임을 가지는 것이 좋다. 책임은 객체의 공용 인터페이스(public interface)를 구성하는데, 이는 객체 지향의 중요한 원리 중 하나인 캡슐화와 깊은 관련이 있다. 책임과 메시지 협력 내의 객체는 다른 객체로부터 요청이 전송됐을 경우에만 자신의 책임을 수행한다. 한 객체가 다른 객체에게 주어진 책임을 다하라고 요청 보내는 것을 메시지 전송(mes..
협력이라는 문맥(context)이 객체의 행동 방식을 결정한다. 객체지향 설계의 전체적인 품질을 결정하는 것은 개별 객체의 품질이 아니라 여러 객체들이 모여 이뤄내는 협력의 품질이다. 객체 하나만 따로 떼어놓고 봤을 때 겉모습이 다소 비합리적이더라도, 조화를 이루고 적극적으로 협력하는 객체를 창조하는 것이 훨씬 중요하다. 객체 하나의 행동이나 상태가 아닌, 객체들 간의 협력에 집중하라. 협력 협력은 다수의 연쇄적 요청과 응답의 흐름으로 구성된다. 협력은 한 사람이 다른 사람에게 도움을 요청할 때 시작된다. 요청받은 사람은 일은 처리하고 요청한 사람에게 지식 혹은 서비스 제공하는 것으로 요청에 응답한다. 어떤 사람이 특정 요청을 받아들일 수 있는 이유는, 그 요청에 대한 적절한 방식으로 응답할 수 있는 지..