객체지향 프로그래밍 질문

객체들이 서로 메세지를 주고 받는다고 하는데

그 메세지가 뭔가요?

단지 다른 객체에게 일하라고 신호를 주는 건가요?

예를 들면 아이템을 사려고 할때

사용자가 "아이템 구매"버튼을 누르면 거기서 인벤토리가 꽉 찼는지 않찼는지

구매하는데 골드는 부족하지 않은지등등을 확인하는 객체들을 만들고

그 객체들에게 메세지를 보내는 건가요?

그런데 도데체 메세지를 어떻게 보내야 하나요?

전혀 감이 잡히지 않아서 그런데 혹시 팁같은게 있나요?

물론 그때 그때 상황에 따라서 메세지도 달라질거 같은데 대부분은 어떤식으로 객체들이

서로 상호작용하게 하나요? 그리고 객체지향을 잘할수 있는 방법같은것을 알려주는 강의 같은것이 있나요?

감사합니다

객체지향의 세계에서 각 객체는 요청한 작업을 수행하는 도중 다른 객체의 도움이 필요할 때 해당 객체에게 요청(메세지)을 보냅니다. 요청을 받은 객체는 해당 요청을 수행한 뒤 다시 요청을 송신했던 객체로 응답합니다. 이렇게 객체지향 프로그래밍은 각 객체들이 서로 '협력’을 통해 시스템을 설계합니다.

객체지향 패러다임을 구현한 현대 언어들은 주로 필드와 메서드로 이루어진 클래스라는 개념을 통해 객체지향을 구현합니다. 이 언어들은 클래스의 인스턴스들을 이용해 주로 instance.method(parameter)와 같은 문법으로 객체에게 요청을 보냅니다.

객체는 이러한 요청을 자율적으로 처리합니다. 받은 요청을 어떻게 처리할 지는 전적으로 그 객체에게 달려있으며, 외부 객체는 해당 객체의 처리에 간섭해서는 안 됩니다. 따라서 객체의 내부는 보호됩니다(캡슐화).

한편 객체들은 받은 요청을 각자가 자유롭게 처리할 수 있습니다. 어떤 객체는 같은 요청을 다른 객체와 다르게 처리합니다(다형성, 상속). 이 특성을 통해 객체는 서로 대체가능성을 가집니다.

메세지는 객체에 대한 요청입니다. C++문법에서 흔히 볼 수 있는 instance.method() 와 같은 코드입니다.

객체지향은 '협력’을 설계하는 패러다임입니다. 각 객체들은 객체가 요청을 수행하는 도중 도움이 필요할 때 다른 객체에게 도움을 요청하고, 해당 객체는 그 요청을 자율적으로 받아 처리하여 응답합니다. 이렇게 각 객체가 시스템의 궁극적인 요청을 처리하기 위해 각 객체가 서로 협력하며 책임을 다해 역할을 수행합니다.

어떤 객체가 그 책임(요청을 처리하고 응답하는)을 더 잘 할 수 있다면 그 객체에게 해당 책임을 부여하여 요청에 대한 최선의 결과를 얻게 합니다. 객체는 자신이 맡은 책임을 충실히 이행하며, 도움이 필요하면 어떤 책임을 더 잘 할 수 있는 객체에게 요청하고, 객체는 해당 요청 또한 충실히 이행하며, 응답합니다.

글이 좀 길어졌는데, 짧게 정리하면 객체의 상호작용은 객체간의 '협력’으로 설계됩니다.

2 Likes

그렇군요 감사합니다 약간 main함수에서 처리를 하다가 연산이 필요할때 함수를 호출해서 해당 연산의 결과를 얻어온것과 비슷하게 함수의 더 업그레이드된 버젼같은 거네요

지금까지 클래스 하나에 모든 함수와 변수를 다 선언하고 사용했었는데
지금까지 객체지향을 하고 있던게 아니였네요…
정말 감사합니다 객체들을 서로 협력하도록 한번 참고해서 더 연구해보겠습니다

객체의 역할은 무엇인가? 라는 의문은 필연적으로 선문답스러운 면모가 있습니다.
객체 하나가 어떤 사건을 인지하고 ▷ 나비효과처럼 객체들이 퍼져 있는 월드에 영향을 주는 오묘한 설계를 저도 상상해본 적은 있습니다만…
진화 실험 같은 시뮬레이션 같은 경우 말고는 일반적인 프로젝트는 정해진 흐름을 구현하는 것이기에
객체의 역할이라는 것은 실로 제한적일 수 밖에 없습니다.
시계로 보자면, 시계 자체를 객체로 보는 것이 아니라 시계 부품 하나 같은 거라고 볼 수 있겠죠.
그러나 시계가 달리기 시합의 시간을 측정하는 상태라면 시계 자체는 객체로 작용하는 것이겠죠.
약간 두서가 없지만,
결국 객체라는 것은 프로젝트가 지향하는 목표에 따라 그 구현 범위가 달라진다고 볼 수 있습니다.
이미 만들어져 있는 효율적인 프레임워크와 라이브러리가 제공하는 기능에 맞춰
객체 그 자체의 성격만 구현하면 되는 것이 일반적인 프로그래밍이라 감히 주장해봅니다.
(그러나 컴퓨터 공학의 기본 지식과 기술은 매우 중요한 것이라 첨언합니다.)

2 Likes

hkk 님이 잘 설명해주셨는데,

일반적인 함수 호출이 강한 결합이라면 ( strong binding )
메세지라는 것은 약한 결합을 이야기 하는겁니다. ( light binding )

받아들일지 말지 어떻게 응답할지는 받아들이는 객체가 주체적으로 판단할 요량이란거죠.

BIOS 의 interrupt 나, 운영체제의 Signal, Message 도 다 그런 맥락입니다.
운영체제에서 응용프로그램으로 직접적인 함수호출이 일어난다면,
stack 사용률이 끝없이 증가할테고,
응용프로그램에 오류가 있다면 운영체제의 오류가 되어버릴테니까요.

그래서 system message pool 로부터 응용프로그램이 필요할때 메시지를 가지고 온다든지,
응답없음이라든지, 운영체제와 응용프로그램이, 객체와 객체가 상호 독립성을 존중하며
적은 자원으로 안정적으로 구동될 수 있는 것이죠.

정말 작은 시스템일때는 독립성을 부여하기 위한 이런 절차가 오히려 비용을 초래합니다만,
시스템이 조금만 커져도 큰 비용절감이 가능해지죠.

component 의 message 처리 개념입니다.
small talk 이라는 언어의 이름 자체에 내포된 개념이기도 하죠.

5 Likes

https://blog.naver.com/rhdnfka94/222015861503

현대에 많이 쓰이는 객체 지향 언어들은

어떤 타입(클래스)이랑 함수(메서드)를 묶어 놓고
그 타입을 함수의 첫번째 인자로 넣고
함수에 필요한 나머지 인자를 넣어서 함수를 호출하는 걸
메시지를 전송한다고 말해요

그러니까 메시지 전송은 함수 호출입니다


보통 f(a,b,c,d) 이렇게 쓸 수 있는 함수를
a.f(b,c,d)라고 쓰면 객체 지향 언어라고 해주더군요

이제 거기에 다형성이랑 타입 계층 구조랑 접근 지정자 같은 걸 넣으면 흔히들 쓰는 객체 지향 언어가 되요


현대 객체 지향 언어에서 객체 간의 메시지 전송은 그냥 함수 호출이에요.
클래스는 쓸데 없이 타입 하나랑 함수를 엮어놓은 거고
메서드는 그냥 함수 호출을 이상하게 표현한 겁니다.

2 Likes

이런 해석에 대한 출처나 근거가 있나요?

뭐 사실 까놓고 말하면 그렇죵 ㅎㅎㅎㅎ
특정 형식으로 만들기위해 코드가 길어지는것도 그렇구용.
특히 그 자바라는 친구가 에… 암튼… ㅋㅋㅋㅋ

사실 객체지향이라는건 그냥 패러다임이라 ㅎㅎㅎㅎㅎ

그냥 제 생각이에요. 링크로 달은 블로그는 제 블로그구요.

사실 자바나 OOP를 잘 아는 건 아니라서 객체지향 많이 하시고 잘 하는 분들의 의견도 듣고 싶어요. 한때 oop를 좀 하기는 했지만 최근에는 oop보다는 함수형을 주로 다뤄서…

'구매’에서 구매하는 '물건 정보’와 '구매자 정보’를 갖고 가서
물건쪽이든 구매자쪽이든 가격과 소지금 비교를 통해 구매 가능/불가능의 메시지를 True/False 같은 느낌으로 '구매’에 리턴하면 메시지가 되는게 아닐가여

어딘가에 요청해서 거기서 무슨 작업을 해주면 요청이고
어딘가에 요청해서 거기서 뭘 확인해주면 메시지같은게 아닐가

이상 OOP 잘 안해본사람의 생각이엇슴미다

객체간에 메시지를 주고 받는 과정은 함수만 존재하는게 아니죠.
언어적으로도 시스템적으로도 말이죠.
물론 함수가 대표적이죠. 눈에 띠니까.
동적 타입을 지원하는 스크립트 언어들 중엔 직접호출이 아닌
대화의 과정을 설계해 놓은 녀석들이 많구요.
그게 light binding 을 의미하는거죠.

전역변수와 같은 계층도, 유지해야할 상태객체라고 볼 수 있고,
함수라는 형태의 호출이 강제되지 않은,
static 객체나 메모리 구조가 있다는 것은
이것 역시 light binding 을 의미하는거예요.
즉시성을 해제하는거예요.
callee 가 아닌 전달 받을 객체가
자신이 원하는 시점에 update / invalidate 된 정보를 가져갈 수 있게 되니까요.

물론 초보에게,

in C

method( some_object, parameters... );


in C++

some_object.method( parameters... );

둘은 같은 일을하는 구조적, 객체지향적 접근일 뿐이다.
라는 설명을 하는건 구조를 이해하는데 도움이 될 수 있겠죠.
이미 hkk 님이 설명해주신 부분이기도 하고.

그런데 좀 뒤로 가면 light binding 과 strong binding 이 훨씬 큰 개념이돼요.
수시로 나와요. 언어를 초월해서.

단지 시험공부라면 교과서에서 주장하는 용어의 정의를 따라가면 되겠지만,
메시지를 주고 받는다는건,
교실에서 학생들이 상대방의 귀에 속닥속닥 말로 이야기 해주는 것 뿐만 아닌,
칠판에 적어놓고 필요한 사람이 읽게하는 행위들도 포함된다는거예요.
상대의 사물함에 편지를 꽂아놓는 행위도 물론 포함되고요.

그래야 나중에 interprocess communication 이나, network system,
transactional memory, operating system 이나 system design,
concurrency 등에서 활용할 수 있는 개념이 되죠.

그냥 전역변수 상태(값) 바까놓고
딴 객체가 그 변수 상태(값) 보고 얘 이상태구나 하고 넘어가는것도
객체간의 '메시지 전달’인거군요
전역변수를 그렇게 쓰는줄은 몰랐는데
새로운거 배우고 감미다

네 그걸 전역 객체스럽게 구현하면 singleton 형태로 만들 수 있죠.
싱글턴 객체 안에서 메서드로도 가공할 수 있구요.

3+3+3+3 보다 3*4가 편하고
손으로 계산하는것 보다 주산이 더 빠른 경우가 많습니다.

본질적으로 같아도
체계가 다르면
사람은 다르게 다룬다고 생각해요.

메시지라고 하니 애매한 부분이 있는데 데이터라고 표현하는게 더 이해하기 쉬울 것 같읍니다


넓은 의미에서 메시지 패싱은 이것저것 포함되는데
적어도 OOP 쪽에서 메시지 패싱은 메서드 호출이라고 보면 되요…

사실 객체가 가지는 인터페이스(객체나 클래스에 딸려있는 퍼블릭 변수 포함)를 써서
뭔갈 하면 넓게 봤을 때 그걸 메시지 패싱이라고 할 수도 있어요


근데 현대 OOP 언어에선 보통 메서드로 하는 걸 메시지 패싱이라고 하는 듯.
그리고 그런 논리에서 이상적으로는 메시지 패싱(메서드)만으로 프로그램을 구성해야 한다고 생각하는 거 같아요
그래서 get set 쓰는 거 같고.

사실 말이 되는 이야기죠.
프로그램을 메서드만으로 구성하면 요구사항이 변경됬을 때, 같은 메서드를 호출해도 다형성(메서드 오버라이딩) 을 통해 타입에 따라 다른 행동을 하는 새 클래스를 추가하는 것으로 해결할 수도 있으니까요.

그런데 프로그램을 함수만으로 구성해서 요구사항이 변경됬을 때 같은 함수를 호출해도 다형성(함수 오버로딩) 을 통해 타입에 따라 다른 행동을 하는 새 타입을 추가하는 것으로 해결하는 것과

무슨 차이점이 있나… 하는 뜻이었습니다. 타입 계층구조의 유무라는 차이점은 있겠네요.


근데 java message passing이라고 검색했더니 구글 첫 결과로 쓰레드 이야기가 나오는 건 좀 놀랐네요
메서드 이야기 나올 줄 알았는데…

시간 나면 스몰토크도 한번 해봐야겠어요

get set property 가 의미하는 것도 light binding 입니다.
set 이 기각될 수도 있음을 말하는거예요.

이라고 제가 말한게 그 개념입니다.
어떤 경우엔 함수로 쌌을 때 light 해지고, 어떨땐 함수를 벗겼을 때 light 해지죠.
껍데기 형식적으로 구별가능한 문제만은 아니예요. 사용에 달린거죠.

그래서 그 과정을 더 명확히 하기 위해서는 전역 객체로 싸든지,
rvalue lvalue 처리에서 대화의 과정을 구체화하기 위해 함수로 싸든지
개발 여력과 필요에 따라 다양한 접근이 가능해지는거죠.

windows 의 신호 전달 체계가 message 라고 네이밍된것도
사람들과 공유할 수 있는 정서적 합의점이 있는거예요.

binding 개념이 단계별로 다양해요. 더 가벼운게 있고 좀 무거운게 있고.
로그인 할 필요없는 DC 같은 커뮤니티의 익명성도
개념적으론 light binding 과 크게 다르진 않아요.