근래의 거의 모든 프로그래밍 객체지향이란 개념으로 구현합니다. 또한, 새롭게 제시되는 방법론 들도 모두 객체지향을 기반으로 제시됩니다. 실세계의 사물을 추상화(Abstraction) 하고, 캡슐화(Encapsulation) 하며, 계층구조는 상속(Inheritance)시키며, 부모와 다른 자식의 특성, 행위는 다형성(Polymorphism) 으로 
구현된 그것, 바로 객체의 구성으로 프로그램을 만들어 나가는 것을 객체지향 프로그래밍 이라 하는 것이죠.

객체지향 프로그래밍



이렇게 정의가 되어 있어도 다시 나오는 질문이 있습니다 : "그래 알겠는데, 도대체 객체지향이 뭐야?, 뭐가 특별하다는 거지?, 왜 객체지향 방법론을 사용해야 하는데?, 어떻게 하는 거지?"

이와 같은 질문에는 다시 객체지향의 개념이 반복되죠. 끝이 없습니다. 도대체 어떻게 하면 객체지향을 제대로 이해 할 수 있을까요?  이 질문에 대한 잘 기술된 글이 있어 번역 포스트 합니다. 무엇이 객체지향이고, 무엇이 객체지향이 아니며, 객체지향을 만족시키려면 어떻게 해야 하는가? 어떤 이득이 있는 것인가? 를 다룬 글 입니다. 대부분의 관점에 동의 하며 특히 아래의 객체지향의 핵심을 집어내는 정의로써 에릭 에반스의 DDD 에서 이 장점을 취하기 위해서는 어떻게 해야 하는가에 대한 내용을 다루고 있습니다.

객체지향 프로그래밍 이란 캡슐화, 다형성, 상속 을 이용하여 코드 재사용을 증가시키고, 유지보수를 감소시키는 장점을 얻기 위해서 객체들을 연결 시켜 프로그래밍 하는 것 입니다.




번역 :

제목 :  What is Object Oriented Programming (OOP)?
http://www.tonymarston.net/php-mysql/what-is-oop.html


들어가는 말

뉴스그룹이나 포럼에서 나는 다음과 같은 질문을 매우 빈번히 접합니다. : 무엇을 객체지향(OOP) 라고 부르나요?, 뭐가 특별한가요? 왜 해야 하죠? 어떻게 하는 거죠?. 이런 종류의 질문을 하는 사람은 보통 비객체지향(non-OO) 프로그래밍에 경험이 있으며, 방법론의 전환을 위해서 잇점이 무엇인지 알고 싶어 하는 것입니다. 짧던 길던 불행하게도 대부분의 답변은 동화같고 애매모호하며, 의미없는 것들 뿐입니다.

비객체지향 언어로 1,000개 이상의 프로그램과 500개가 넘는 객체지향 기능의 PHP 프로그램을 작성해본 경험으로 이 논쟁에 기여를 해보려 합니다. 몇몇 객체지향 순혈주의자들은 내가 그들의 방법을 따르지 않는다고 생각하고, 나또한 그들의 방법론을 따르는 것을 거부합니다. 이것에 대한 나의 대답은 "세상에는 객체지향을 유일한 방법이란 없다" 입니다. 사람들은 나의 방법이 틀렸다지만, 그들은 전통적인 실수를 하고 있습니다. 내 방법이 틀리지 않은 간단한 이유는 "작동한다" 입니다. 길 막고 물어 봐도 "작동 하는 것이 틀릴 수는 없습니다. 작동하지 않는 것이 옳을 수는 없습니다."  내 방법이 틀린 것이 아니라, 약간 다를 뿐 입니다. 

사람들이 전혀 쓸모 없는 답변을 하는 하나의 이유는 그들이 그렇게 배웠으며, 배운 것 이상으로 생각할 능력이 없기 때문입니다. 또다른 이유는 객체지향에 대한 설명들이 막연하고, 여러가지 의미로 해설될 수 있으며, 어떤 것이 해석 될 때는 '잘못 해석' 될 가능성이 있습니다.  심지어 추상화 Abstraction, 갭슐화 Encapsulation, 정보은닉 Information-Hiding 의  어떤 기본 용어들은 사람들 마다 다른 뜻으로 정의하고 있습니다. 사람들이 OOP의 기본개념들에 동의하지 않는 데, 어떻게 구현에 동의 할 수 있겠습니까.


OOP가 아닌 것은 무엇인가?

내가 반박할 첫번째는 non-OOP 에도 이미 존재 하고 있음에도 OOP 에서만 가능한 것처럼 말해지는 것들입니다.

OOP는 실세계 real world 를 모델링 하는 것이다.

OOP는 실세계를 모델링 하기 위해 추상화 Abstraction 을 사용하는 프로그래밍 패러다임이다. 더 나은 도메인 분석과 시스템 디자인의 통합을 제공 함으로써 실세계 모델링을 더 잘 지원한다. 

OOP 가 다른 방법론들 보다 실세계 모델링을 더 잘 지원한다는 것은 쓰레기 같은 말입니다. 모든 컴퓨터 프로그램은 프로세스를 모델링하는 방법을 찾는 것 입니다. 모델이 잘 못 됐다면 소프트웨어도 잘 못 됩니다. 개념적 모델은 실세계의 분석으로 만들어 집니다. 그리고 컴퓨터 소프트웨어는 전적으로 개념적 모델에  기반합니다. OOP는 더 잘 모델링하는 것을 보장하지 않습니다. 모델의 구현방법이 약간 다를 뿐입니다.

"추상화 Abstraction" 또한 해석해야 하는 용어 이고, 잘 못 해석되는 용어 입니다. "추상화의 진정한 의미 이해하기" 의 논의 에서 처럼, 추상화라는 말은  미켈란젤로의 작품을 보아야 할  때, 피카소의 작품을 떠올리게 합니다.

고객에게 필요한 X,Y,Z 기능이 없고, A,B,C 의 기능을 가진 소프트웨어가 만들어지는데는 이유가 있습니다. 고객이 요구사항 분석서에  X,Y,Z 를 언급하지 않았으며, 분석가가 이것을 집어내는 것을 실패했기 때문입니다. 내 오랜 경력에 비추어 이런 일은 빈번하게 벌어집니다.

OOP 에 의해 실세계가 모델로 바로 매핑된다는 것에 모든 사람들이 동의하지는 않습니다. 더 심하게는 프로그램은 세상을 모델링 하는 것이 아니라 세상의 부분만을 모델링 할 수 있다 입니다. 


OOP는 코드 재 사용을 위한 것이다.

객체지향시스템은 코드를 재사용 함으로써 생산성을 증대시키고, 품질을 향상시키며, 비용을 축소 시키는 것을 약속한다.

쓰레기같은 말이다. 이것은 코드 재사용이 non-OOP 에서는 불가능하고 OOP 에서만 가능하다는 의미를 내포하고 있습니다. 코드 재사용은 코드를 어떻게 작성 하느냐에 달려 있는 것이지, OOP가 코드 재사용을 보장하는 것이 아닙니다. non-OOP 언어로도 재사용 가능한 라이브러리를 작성하는 것이 가능하며,  OO 언어로도 재사용 불가 코드가 만들어 집니다.

어떤 언어에서 같은 코드 블록이 100군데 이상 중복 되는 것은 언어 능력의 문제가 아닙니다. 또한, 어떤 언어로도 코드 블록을 재사용 가능한 라이브러리로 만들고 100군데에서 호출하게 할 수 있습니다.

OOP에 대해 수년동안 들어온 약속중에 하나는 , 소프트웨어 벤더들이 이미 작성해 놓은 라이브러리를 사용 가능하게 한다는 것입니다. 프로그래머들에게는 클래스를 작성하는 대신에 이미 작성해 놓은 클래스를 사용하라고 말했습니다. 그것은 '바퀴를 재발명하는 것'이라 면서 말이죠. 꿈은 실현되지 않았습니다. OOP 는 많이 약속 하고 조금 배달 한다는 것을 증명했을 뿐이죠.


OOP는 모듈화에 대한 것이다.

어떤 오브젝트에 대한 소스 코드는 다른 오브젝트 코드와 별개로 작성되고 관리되어질 수 있다. 한번 만들어지면 시스템 안으로 쉽게 전달 할 수 있다.

모듈화 프로그래밍은 non-OO 언어에도 수년동안 존재해 왔습니다. 그래서 이 논재는 객체지향이 비객체지향보다 낮다는 설명으로 쓰일 수 없습니다. 모든 언어는 하나의 어플리케이션 소스코드를 한개의 파일에 집어넣을 수 있습니다. 또한 여러개의 작은 모듈로 나누어서 모듈 별로 파일에 넣고, 유지보수하고, 컴파일 할  수 있습니다.

게다가, 여러개의 클래스로 구성된 어떤 소프트웨어는 자동적으로 모듈화 됩니다. 중요한 요소는 모듈 또는 클래스를 잘 디자인 하는 것입니다.


OOP는 플러그를 가능하게 하는 것이다.

특정 오브젝트가 문제가 있다고 밝혀지면, 여러분은 어플리케이션에서 그 오브젝트를 간단하게 제거하고 다른 오브젝트를 플러그 하듯이 대체할 수 있다. 이는 실세계와 유사하다, 볼트가 부러지면 전체 머신이 아니라 볼트만 대체하면 된다.

이것은 다른 모듈을 손볼 필요없이 개개의 모듈이 독립적으로 수정되고 컴파일 되고 삽입될 수 있다고 말하는 모듈화의 경우와 같다.


OOP는 정보 은닉에 대한 것이다.

객체의 인터페이스와만 상호작용함으로써 내부 구현은 바깥 세상으로 부터 감추어 질수 있다.

첫 부분, 여기서 설명 하는 것은 '구현' 의 은닉이지 '정보'의 은닉이 아니다. 어떤 사람들은 무의식적으로 객체의 데이터가 포함된다고 가정합니다. 다시 말하면, API 뒤로 코드를 감춘다는 것은 뷰로 부터 감춘다는 것이지 객체로 부터 데이터를 감춘다는 말이 아닙니다.

두번째 부분 , 구현 은닉은 OOP의 목적이 아닙니다. 이것은 캡슐화의 부산물 입니다. 바깥 세상은 오브젝트의 메소드 이름만을 볼 수 있습니다. 메소드 뒤의 코드를 볼 수 있는 것이 아닙니다.

세번째 부분, 구현 은닉은  OOP만의 특별한 것이 아닙니다. 인터페이스를 가진 80년대에 작성된 상업용 COBOL 패키지를 기억합니다. 이 패키지의 벤더는 우리의 코드에서 호출해서 사용할 수 있도록 컴파일된 패키지를 제공 했었습니다. 우리는 그 서브루틴의 소스코드를 볼수 없었습니다. 우리는 단지  API 목록과 입력과 출력의 기술서를 받았습니다.



OOP는 메시지 전달에 대한 것이다.

메시지 전달이란 한 객체에서 다른 객체로 데이터를 전달하거나, 다른 객체의 메소드를 실행 시키는 것이다.

객체지향 언어에서 객체가 메소드를 실행시키는 것은 비객체지향 언어에서 함수나 프로시저를 실행시키는 것과 구별되는 것입니다. 비객체지향 언어에서의 함수나 객체 메소드를 실행 시키는 것은 "메시지 전달 Message Passing" 이 아니라 "호출 calling" 이라고 부릅니다. 사실 몇몇 언어에서는 서브루틴을 실행시키기 위하여 "호출" 이라고 부르는 단어가 필요합니다.

non-OO : $result = function(arg1, arg2, ...)
OO :        $result = $object->function(arg1, arg2, ...)

각각의 실행의 결과는 정확하게 동일합니다. - 통제권은 피호출자로 넘어가고 호출자는 기다립니다. 통제권은 피호출자가 종료 될때까지 반환되지 않습니다.

나는 과거에 메시징 스프트웨어를 작업해 보았습니다. 그것이 완벽하게 다르다고 말할 수 있습니다.

첫번째로 메시징 소프트웨어는 한 프로세스에서 다른 프로세스로 메시지를 전달하는 것을 허용합니다. 같은 프로세스에서 다른 모듈로의 메시지 전달이 아닙니다. 같은 어플리케이션의 한 non-Modal 폼에서 다른 non-Modal 폼으로 메시지를 전달 하는 것이었죠. 이것은 오로지 분리된 sendMessage() 함수와 수신 모듈에서의 수신되는 메시지를 처리하기 위한 receiveMessage 트리거 로써 가능합니다. 수신자가 송신자에게 응답하는 방법은 메시지를 전송하는 방법 이외에는 없습니다. 

두번째로 행위( Behavior )가 전혀 다릅니다.

그것들은 비동기 입니다. 이것은 호출자는 메시지를 큐에 전송하고 다른 프로세스를 처리합니다. 피호출자가 통제권을 반환 하는 것을 기다릴 필요가 없습니다. E-mail이 전통적인 메시징시스템의 예 입니다.

메시지큐는 프로세스의 개수와 메시지의 갯수에 제약받지 않습니다. 수신 프로세스는 메시지 큐의 첫번째 메시지를 꺼내고, 또 다음 것을 꺼냅니다.

수신자는 메시지를 받자마자 송신자에게 acknowledgement 를 전송합니다. 또는, 처리된 메시지를 반환 합니다.

메시지 시스템은 acknowledgement 또는 결과를 전송하는 코드를 포함하고 있어야 합니다.

보다시피 객체가 메소드를 확성화 시키는 메커니즘은 비객체지향 함수가 활성화 시키는 것과 정확하게 동일합니다. 메시징 시스템의 메시지 전송과는 무관합니다.



OOP 는 책임의 분리에 대한 것이다.

각각의 객체는 구별되는 역할과 책임을 가지고 있는 작은 머신으로 보여질 수 있다.

언어의 문제가 아니라 전적으로 모듈이 어떻게 작성되느냐에 달려 있습니다. COBOL과 같은 절차적 언어로도 독립적인 모듈을 작성할 수 있습니다. 반대로 객체지향 언어로도 지극히 종속적인 모듈이 작성될 수 있습니다. 


책임분리의 문제는 그 뜻이 정확히 무엇이든지 상관없이 해석하는 사람마다 다릅니다. 어떤 사람은 SELECT, INSERT, UPDATE, DELETE 와 같은 데이터베이스 오퍼레이션이 그를 필요로 하는 객체에 존재해야 한다고 생각하고, 어떤 사람은 그것들을 한데 모은 별도의 객체에(Data Access Object , DAO) 넣어야 한다고 생각합니다. 어떤 프로그래머는 테이블 마다의 DAO를 작성해야 한다고 생각하고  어떤 프로그래머는 모든 데이터베이스 테이블을 취급하는 한개의 DAO를 작성해야 한다고 생각합니다. 여러분은 책임들을 분리하기 전에 언어와의 별도의 디자인 결정에 의해 책임을 구별해야만 합니다.

내 모든 경험을 통틀어 "기술의 난이도"에 의해 실패한 단 하나의 프로젝트는 "책임의 분리"에대한 모든 것을 알고 있다고 생각하는 객체지향 설계 전문가와 함께 한 것이었습니다. 그들은 각각의 책임을 가지는 모듈로 나누고, 디자인 패턴을 이용하여 설계하였습니다. 이 결과로 UI 에서 데이터베이스 까지는 적어도 10개의 레이어를 가지도록 설계 되었습니다. 이로써 컴포넌트는 필요 이상으로 복잡해 졌고 테스트와 디버깅은 완전히 악몽이었습니다. 그 결과 고객의 시간과 비용은 엄청 증가하였습니다. 그 고객은 플러그를 뽑고 전체 프로젝트를 중단하여 손실을 제한하였습니다. 구식의 비객체 방법론으로 한시간도 채 안걸리는 컴포넌트를 최신 유행하는 객체지향 기술로는 10일이 걸렸습니다.

덧붙여서, "관심이 분리된 Seperation of Concern" 여러개의 클래스/모듈 로 자동으로 구성된 소프트웨어는 특정 엔터티에서는 "걱정거리 Concern"로 고려 되어 질 수 있습니다. 중요한 요소는 클래스 /모듈이 엔터티의 요구사항을 어떻게 잘 취급하는가 입니다.



OOP는 배우기가 쉽다.

OOP는 이전의 접근방법보다 배우기가 매우 쉽다. 이 접근방법은 개발과 유지보수를 단순하게 하며,  다른 절차적 방법론 보다  분석, 코딩, 복잡한 상황의 이해도를 직관적으로 만들어 준다.

마케팅 전략일 뿐입니다. 모든 언어/도구/패러다임은 그 가치보다 모든 것이 좋다고 제안됩니다.  무엇을 사용하느냐가 아니라 어떻게 사용하느냐가 중요합니다. 유능한 프로그래머에 의해 사용되는 '구식' 언어는 '신식'언어의 광고되는 생산성보다 몇배는 더 큽니다.

한 사람의 학습 능력은 종종 가르치는 사람과 가르치는 도구에 의해 제한 됩니다. 나는 프로젝트를 성공 시키는 것 보다 너무 비효율적이고, 복잡하게 하는 것을 배우는 것을 두려워 합니다. OOP를 가능하게 하는 방법은 "단 한가지" 뿐이라고 주장하는 선생님이 너무 많습니다. 나는 이것에 가장 동의하지 않습니다. 나는 소위 전문가 라고 하는 사람들의 방법을 무시하고도  비객체 지향 언어로 작성된 것을 성공적으로 객체지향언어로 마이그레이트한 경험이 많습니다.

어떤 사람은 프로시저 함수를 클래스로 감싸는 것 만이 OOP가 아니라고  나에게 말 했습니다. 나는 동의 하지 않습니다. 그것은 간단 합니다. 유일한 트릭은 연결된 함수를 한곳에 모으고( 캡슐화 라고 말하는) , 객체로 관리될 수 있도록 조정 합니다. 여러분이 클래스로 할 수 있는 정말 똑똑한 것은 부모 또는 추상 클래스를 상속(Inheritance)을 통하여 수개의 서브클래스로 확장하는 것 입니다. 다형성(Polymorphism)을 이용하여 서로 다른 클래스의 메소드/함수를 사용 가능하게 할 수도 있습니다. 나는 함수들이 잘못 혼합된 매우 많은 예제들을 접해 봤습니다. 관계 없는 함수가 한 클래스에 있으면 안됩니다. 나는 상속의 과잉 사용으로 매우 복잡한 계층구조를 가져서 유지보수와 진보가 거의 힘든 경우를 보았습니다.  나는 다른 프로그래머에게 인상적으로 보일 목적 이외로는 볼 수 없는 객체지향의 모든 기능을 사용하여 코드를 더욱 불분명하게 만드는 프로그래머를 본적이 있습니다. 그들은 너무 단순하면 틀렸다고 생각하는 듯 합니다. 아마도 KISS( Keep-It-Simple, Stupid. 단순하게 하란 말야. 멍청아!) 원칙을 들어본적이 없어 보입니다.


OOP는 행위자(actors) 와 행위(actions) 에 대한 것이다.

객체지향 프로그래밍이란 소프트웨어 개발을 행위자와 행위를 코드를 이용하여 분해하고 모듈화하는 것이다.

이것은 매우 모호하고, 전혀 쓸모 없는 말입니다.



OOP 는 늦은 바인딩( late binding )에 대한 모든 것이다.

'늦은' 이라는 것은 (어떤 바이너리를 로드할 지 , 어떤 함수를 호출 할지) 바인딩을 가능한한 늦추는 결정이다. 컴파일 타임에 바인딩 (early) 하기 보다는 호출 될 때 바인딩 하는 것이다.

빠르거나 늦게 바인딩 되는 것은 객체지향과 비객체지향 차이와 무관합니다. 비객체지향 언어도 늦은 바인딩을 지원합니다. 비객체지향 언어가 늦은 바인딩을 지원한다고 해서 마술같이 객체지향으로 바뀌지 않는 것 처럼, 객체지향 언어가 빠른 바인딩을 한다고 해서 비객체지향 언어가 되는 것이 아닙니다.


알겠지만, 위는 너무 불명확하거나 OOP에 한정된 것이 아니어서 구별되는 기능으로 사용될 수 없는 것들을 기술한 것입니다.



객체지향 언어란 무엇인가?

아래의 것들을 제공한다면 그 언어는 객체지향언어 목록에 추가 될 수 있습니다.

객체-지향 언어의 5가지 특성
1. Object
2. Class

3. Encapsulation
4. Inheritance
5. Polymorphism

5가지 특성이 무엇인지에 대한 설명 포스트: 객체-지향 프로그래밍이란 무엇인가? 다섯개의 기반 개념 참조 하세요.


클래스는 엔터티의 프라퍼티(데이터) 와 그 프라퍼티들에 작동하는 메소드( 함수 또는 오퍼레이션) 들을 정의(캡슐화 Encapsulation) 합디다. 엔터티의 프라퍼티나 메소드는 클래스 바깥에 정의 되어서는 안됩니다.


객체지향 이란 무엇인가?

여러분이 믿고 싶어하는 것보다 훨씬 단순 합니다. 사람들은 실제의 그들 자신보다 더 영리해 보이기 위해 더욱 복잡한 정의를 사용합니다. 여기에 진짜 정의가 있습니다.

객체지향 프로그래밍 이란 캡슐화, 다형성, 상속 을 이용하여 코드 재사용을 증가시키고, 유지보수를 감소시키는 장점을 얻기 위해서 객체들을 연결 시켜 프로그래밍 하는 것 입니다.


객체지향 프로그래밍을 하기 위해서는 객체지향 언어가 필요합니다. 캡슐화, 상속, 다형성을 지원한다면 객체지향 언어라고 말 할 수 있습니다. 다른 기능들도 지원 할 수 있지만 그것들은 그닥 중요하지 않습니다.  이는 개인적인 의견이 아니라 객체지향 용어를 발명한 사람의 의견 입니다. Bjarne Stroustrup 은 그의 문서 Why C++ is not just an Object Oriented Programming Language: 섹션 3 에서 지금의 널리 사용되는 "객체지향" 이라는 용어를 제시하였습니다.

언어 또는 기술은 다음을 직접 지원 한다면 객체지향 이다.
1. 추상화 - 클래스나 객체를 제공한다.
2. 상속 - 이미 존재하는 것으로 부터 새로운 추상화를 만들어 낼 능력을 제공한다.
3. 런타임 다형성 - 수행시간에 바인딩 할수 있는 어떠한 폼을 제공한다.


많은 객체지향 언어들은 나중에 더 많은 기능들을 추가 하였고, 몇몇 사람들은 이 부가 기능들을 객체지향을 결정하는 요소라고 생각하지만 나는 전혀 동의하지 않습니다. 이는 온도조절기나 네비게이션이 없다고 자동차를 자동차가 아니다라고 말하는 것과 같습니다. 이것들은 구별되는 기능이 아니라 선택 사양 입니다.

바퀴가 있다고 해서 자동차라고 말 하는 것 또한 틀린 것입니다. 바퀴를 가졌다고 모든 것이 차가 되는 것은 아닙니다. 손수레에 바퀴가 있다고 해서 자동차가 되는 것은 아닙니다. 이것은 구별되는 기능이 아닙니다. 비객체지향 언어에 이미 존재하는 것이기 때문에 "모듈성", "재사용성", "메시징"을 비객체와 객체를 구별하는 기능이 아니라고 말하는 간단한 이유입니다.


OOP 와 non-OOP 의 차이점



비객체와 객체의 차이점을 설명하는 가장 좋은 방법은 실제 예제를 보는 것입니다.

다르게 정의 됩니다.

함수는 필요한 것을 가진 코드의 블록으로 정의 됩니다. 각각의 함수 이름은 어플리케이션에서 유일해야 합니다.

function fName ($arg1$arg2
// function description
{
    ....
    
    return $result;
    
// fName


클래스 메소드는 클래스 정의의 경계로써 규정됩니다. 각각의 클래스 이름은 어플리케이션에서 유일 해야 합니다. 각각의 클래스는 클래스 내부에서 유일한 이름을 가지는 다수의 함수(메소드라고 알려진)들을 가질수 있습니다. 어플리케이션에서 유일할 필요는 없습니다. 사실 공통의 함수/메소드 이름을 가지는 것은 다형성에서 필요로 하는 공유의 능력을 위해서 입니다.

class cName
{
    function fName ($arg1$arg2
    // function description
    {
        ....
        
        return $result;
        
    } // fName
    
// cName



접근 방법이 다릅니다.

함수/클래스는 그 정의가 로드되기 전에 접근될 수 있음을 주목해야 합니다. 

함수를 호출하는 것은 직접적입니다.

$result = fName($arg1$arg2);


클래스의 메소드를 호출하는 것은 직접적이지 않습니다. 먼저 클래스의 인스턴스를 생성해야 합니다. 그리고  오브젝트의 함수 이름을 통해서 접근합니다.  오브젝트 이름은 어플리케이션에서 유일 해야 합니다.

$object = new cName; 
$result = $object->fName($arg1$arg2);


다수의 다른 복제본을 가지고 있습니다.

함수는 접근되기 전에 인스턴스화 될 필요가 없습니다. 단 한개의 카피본 만이 존재하기 때문이죠.

클래스 메소드는 오브젝트로 인스턴스화 된 후에만 접근될 수 있습니다. (정적 메소드로 정의된 경우를 제외하고) . 같은 클래스로 서로 이름이 다른 다중의 오브젝트로 인스턴스화 시킬수 있습니다.
 
$object1 = new cName;
$object2 = new cName;
$object3 = new cName; 

 
인스턴스화 시키지 않고 정적메소드에 접근할 수 있다 하더라도, non-Class 함수의 접근보다 나을 것이 없습니다. 오브젝트에 의해 실제로 사용되지 않으며, 객체지향 프로그래밍의 한 부분으로 고려되는 사항이 아닙니다.


다수의 엔트리 포인트를 가집니다.

함수는 단일의 진입점을 가집니다. 그것은 함수 이름 그 차체 입니다.
오브젝트는 여러개의 진입점을 가집니다. 각각의 메소드 이름 입니다.


상태 관리를 위한 다수의 메소드를 가집니다.

함수는 기본적으로 상태를 가지지 않습니다. 이것은 호출 될 때마다 새로운 실행으로 취급된다는 것을 의미합니다. 이전 실행과는 아무 연결이 없습니다.

오브젝트는 상태를 가집니다. 각각의 오브젝트의 메소드가 호출될 때 마다 오브젝트의 상태가 변경됩니다.

이것은 함수와 클래스 메소드 모두 로컬 변수를 사용한다는 점에서 같은 방식으로 동작합니다. 로컬 변수란 함수나 클래스 메소드의 범위를 넘지 않는다는 것을 뜻합니다. 그리고, 실행들 사이에서 저장되지 않는다는 것이죠.


함수가 서로 다른 수행에서 값을 기억할 수 있는 방법은 정적 변수를 사용하는 것입니다.

function count () {
    static $count = 0;
    $count++;
    return $count;
}

이 함수는 호출 될 때마다 이전 호출 값보다 하나더 증가된 값을 반환 합니다.  static 키워드가 없다면 항상 '1' 이라는 값을 반환 합니다.

클래스 레벨에서 선언된 변수를 함수(메소드) 범위 밖으로 저장시키려면 다음과 같이 하면됩니다.


1
<span style="font-size: 11pt; ">class calculator{    // define class properties (member variables)    var $value;        // define class methods    function setValue ($value)     {        $this->value = $value;                return;            } // setValue        function getValue ()     // function description    {        return $this->value;            } // setValue        function add ($value)     // function description    {        $this->value = $this->value + $value;                return $this->value;            } // setValue        function subtract ($value)     // function description    {        $this->value = $this->value - $value;                return $this->value;            } // setValue    } // cName</span>


클래스/오브젝트의 참조는 $this->varname. 과 같은  $this->  프리픽스 에 의해 참조 된다는 것에 주목하세요. 
this 키워드로 참조되지 않은 $varname 변수는 로컬 변수로 취급됩니다.

각각 인스턴스는 자신의 변수를 가지고 있습니다. 같은 클래스로 부터 나왔을 지라도 하나의 오브젝트의 컨텐츠는 다른 오브젝트와 독립적입니다. 


(실제 예제 - 캡슐화, 상속, 다형성의 예제는 번역에서 생략합니다. 예제는 원문을 참조하세요.)


결론.


많은 사람들이 OOP의 의미를  서로 다른 단어로 묘사합니다. 문제는 그 단어들이 오역되기 쉽다는 것이죠. 루이스 캐롤의 험프티-덤프티가 자칭한 유리창 너머로 볼때 처럼.

내가 이 단어를 사용할 때는 내가 선택한 뜻을 의미해, 더도 덜도 아니야



OOP의 창작자가 사용한 단어를 사용할 때, 그 단어에 다른 뜻을 적용한다면, 다른 사람은 여러분의 단어를 또 다른 뜻으로 적용합니다. 그것은 원래와 전혀 관계 없는 것으로 끝이 납니다. 

객체지향과 비객체지향을 구별하는 데에느 단지 세가지 기능이 있습니다. 이것들은 캡슐화, 상속, 다형성 입니다. 이거 이외에는 헛소리 입니다. 객체지향 프로그래밍은 프로그래밍 언어에서 이 기능들을 이용하는 것입니다. 높은 재사용성과 낮은 유지보수 비용은 보장될 수 없습니다. 전적으로 이 기능들을 어떻게 구현하느냐에 달려 있습니다.

몇몇 사람들은 내가 OOP에 대해 너무 단순한 관점을 가졌다고 비난합니다. "필요이상으로 단순화 시켰다거나", "필요이상으로 복잡화 했다 거나" 라고 하는 대신에 말이죠. KISS 원칙의 오래된 추종자로써 나는 다른 사람들을 가르치기 쉬운 더욱 적절한 관점을 알고 있습니다.

### 끝.


[출처]http://vandbt.tistory.com/10

'프로그래밍 개론' 카테고리의 다른 글

iBATIS 란?  (0) 2015.11.06
인터셉터 (Interceptor)  (0) 2015.11.06
자카르타 프로젝트  (0) 2015.10.16
리버스 엔지니어링  (0) 2015.10.11
자바 용어  (0) 2015.10.10
블로그 이미지

532

처음 프로그래밍을 시작한 개발자들은 Hello World!를 기억 할 것이다. Hello world가 Hell World가 될 줄 몰랐던 한 개발자의 이야기. 게시글의 출처를 표기하며, 출처를 남기지 않고 펌을 하는것에 대해 법적 책임을 묻지 않습니다.

,