객체-지향 디자인은 위기에 빠진 소프트웨어를 구할 수 있는 메시아 처럼 받아들여 집니다. 진짜 메시아처럼 그 정체를 정확히 아는 사람도 얼마 없다라는 것도 닮았군요. 소프트웨어 개발의 어려운 점은 개념 자체 이해가 어렵다는 것이 크다고 생각합니다. 이 블로그에서 개념에 집착하는 이유가 거기에 있습니다. 

객체-지향 언어, 객체-지향 디자인, 객체-지향 프로그래밍 이란 용어는 아마도 가장 이해하기 어려운념이며, 구원자를 앞에 두고 알아보지 못하고 있는 것 같은 상황입니다. 객체-지향을 설명하는 수많은 책과 글이 있음에도, 정확히 이해하지 못하는 상황에 빠져 있다는 것은 무엇인가 문제가 있음을 증명하고 있습니다.

주된 이유는 객체-지향이라는 개념이 모호한 용어의 조합으로 설명하기 때문이며, 사람에게 익숙한것은 객체-지향이 아니라 절차적 프로그래밍이라는 생각이 들기도 합니다. 기본적으로 사람의 사고 체계의 기본 단위는 절차적입니다. 한 발짝 뒤로 물러 서서 보면 절차를 감싸고 있는 객체가 있음에도 희안하게 그게 잘 보이지 않습니다.

객체-지향을 좀더 쉽고 정확하게 설명하자, 그리고, 객체-지향이 만들어 내는 현상에 현혹되지 말고 핵심을 설명하자는 것이 객체-지향을 수차례에 걸쳐 포스팅 하는 이유입니다.

이전 포스트 : 객체-지향 프로그래밍 이란 무엇인가 (OOP)? 는 객체-지향의 각론에 대한 이야기입니다.  

간단한 프로그램을 작성한다면 구조적 프로그래밍으로도 충분합니다. 뉴튼의 만유인력의 법칙 만으로도 태양계 행성들과 자연계의 움직임을 근사값에 가깝게 설명할 수 있는 것 처럼 말이죠. 하지만, 복잡한 프로그램을 관리가능하게 작성하려면 아인슈타인의 상대성이론을 적용해야 합니다. 그게 문제 인거죠. 만유인력의 법칙이 구조적 프로그래밍 이라면 상대성 이론이 객체-지향 프로그래밍 입니다.

객체-지향을 설명하는 많은 글들 중에 저의 생각과 일치하는 책이 있어, 객체-지향 프로그래밍 개념에한 단락을 번역 포스트 합니다. 98년에 출판된 책인데 번역서는 없더군요.  바로 Stephen Gilbert 와 Bill McCarty의 저서 Object-Oriented Design in Java, published by Sams, 1998 입니다. 


객체-지향 프로그램이란 상호작용 하는 객체의 집합 입니다.




객체-지향을 정확하기 이해하기 위한 5개의 개념 정의와 중요한 관점에 대해 정리해 보자면, 

1. 객체란 무엇인가?
데이터, 행위, 아이덴티티를 가지고 있는 것.

2. 클래스란 무엇인가? 그리고, 객체와 클래스의 차이는 무엇인가?
클래스란 객체를 생성하는 청사진 이다.

3. 캡슐화란 무엇인가?
행위와 상태를 포장하고 외부에 노출할 것과 감출 것을 결정하는 것. 외부에 노출되는 모든 것을 인터페이스 interface 라고 할 수 있다.

4. 상속이란 무엇인가?
가족 관계를 나타내는 것이다. 자식은 부모의 자산을 이용할 수 있으며, 코드 재사용이 첫번째 달성되는 것이며,  상속은 클래스의 계층 구조를 표현 할 수 있게 되는데, 계층 구조는 그 구조 자체만으로 수 많은 정보를 포함 할 수 있다. 계층 구조를 표현하는 것이 두번째 핵심이다.

많은 문서에서 상속을 코드 재사용의 관점에서 기술하고 있지만, 상속의 핵심은 계층구조를 표현 하는 것입니다. 재사용만을 목적으로 상속을 이용한다면 가장 강력하게 커플링된 재사용방법을 쓰고 있는 것입니다.  공통 라이브러리를 사용하는 것이 훨씬 좋은 방법이죠. 계층구조를 포함할 목적이 아니라면 상속을 사용해서는 안되며, 코드 재사용 보다 계층구조의 표현이 상속에서 더욱 중요한 개념이다 라는 것입니다. 

 
5. 다형성이란 무엇인가? 
캡슐화, 상속과 함께 동작 함으로써 객체-지향 프로그램의 흐름 제어를 단순화 하는 것 입니다.

다형성을 설명하는 많은 문서는  
서브클래스의 오버라이드된 메소드가  다른 작업을 할 수 있어서 다양한 형태라는 다형성이라고 설명하는데 포커스가 맞춰 있지만 다형성의 핵심은 흐름 제어 Flow of Control 를 객체로 처리 하도록 단순화 하는 것 입니다.



아래는 
Stephen Gilbert 와 Bill McCarty의 저서 Object-Oriented Design in Java, 1998 의 객체-지향 프로그래밍 설명 부분의 번역 입니다.


번역 : 

객체-지향 프로그램 Object-Oriented Programs

객체-지향 프로그래밍은 오늘날 프로그램의 복잡성을 극복하고 있는 듯 합니다. 프로시저를 object라고 하는 유닛으로 그룹화 함으로써 프로그램은 더 적은 블록을 요구하고 결과로 단순해 졌습니다.


OOP 새로운 것이 아니다? : Is Nothing New?

객체-지향 프로그래밍을 공부하다 보면, OOP에 대한 매우 다른 관점의 말들이 오간다는 것을 쉽게 알아 차릴 수 있습니다. OOP의 다양한 책과 문서들을 읽어보면 사람들이 전혀 다른 것에 대해 이야기 하는 것처럼 보인다. 모든 잡설들을 제고하고 나면 '혁명적 revolutionary' 과 '혁신적 evolutionary' 이라는 두가지 관점이 있다는 것을 알 수 있다. 혁명적 관점을 변론하자면 OOP는 맨손으로 프로그램을 만들던 전통적인 방법과 전혀 다르다는 것이다. 반면에 혁신가의 입장에서 보면, OOP는 전통적인 개념의 재포장 일 뿐이라고 말합니다. 아마도 각각의 견해는 맞는 것도 있고 틀린 것도 있습니다.

절차적 언어로 명확하고, 이해하기 쉬운 프로그램을 작성하는 것이 가능하다고 가정하면 혁신가의 말이 옳습니다. 그리고 객체지향 언어로 작성하더라도 이해할 수도, 관리할 수도 없는 코드가 작성될 가능성이 있습니다. 그러나 혁신가들은 OOP 프로그램이 절차적인 프로그램과는 기반적으로 다른 방법으로 구성된다는 것을 인지하지 못했습니다.


혁명가들은 OOP 디자인 프로세스가 다른 도구와 다른 추상 타입을 사용하며, OOP 프로그램은 함수적 분해를 하지 않는다는 것을 지적합니다. 혁명가들은 OOP 디자인의 명확성과 이해용이성을 과대평가 하는 듯합니다. 잘 설계되고 구현된 절차적 프로그램은 개판으로 짜여진 프로그램 보다 절대적으로 낫습니다. OOP 와 객체지향 언어는 아이디어를 명확하게 표현할 수 있는 도구를 제공하는 것이지, 즉각적으로 효과가 나타나는 만병통치약이 아닙니다. 


주: 
혁명가 : 패러다임이 완전히 다르다는 견해를 가지고 있는 사람. 
혁신가 : 이전의 기술이 개선 되었을 뿐이라는 견해를 가지고 있는 사람.



객체지향 프로그램의 다섯개의 기반 개념.

1. Objects
2. Classes
3. Encapsulation
4. Inheritance
5. Polymorphism

"객체지향 프로그램은 어떠한 목적을 이루기 위해 협업하도록 구성되어지는 객체들의 집합이다."

객체란 무엇인가? What Are Objects?

프로시저를 구조적 프로그램을 작성하는데 사용하다고 단정하면, 객체란 객체지향 프로그램을 작성하는데 사용 되는 것 입니다. 객체지향 프로그램은 어떠한 목적을 이루기 위해 협업하도록 구성되어지는 객체들의 집합입니다. 

모든 객체는 : 

데이터를 가지고 있습니다. - 데이터는 객체의 상태를 기술하는 정보를 저장합니다.
행위의 집합을 가지고 있습니다. - 이 행위들은 메세지를 받았을 때 객체가 어떻개 해야하는지 알고 있는 것 입니다.
개체를 구분하는 아이덴티티를 가지고 있습니다. - 어떠한 객체를 다른 객체와 구분하는 것을 가능케 합니다. 

구조적 프로그램에서 사용되는 레코드,구조체 처럼 객체도 데이터를 담고 있습니다. 이처럼 생각하면 객체는 이전 섹션에서 보았던 급여관리 프로그램에서 보았던 하나의 직원 레코드 처럼 보입니다. 객체의 데이터는 객체의 상태를 표현하기 위해 사용됩니다. 예를 들어, 객체의 데이터를 가지고 그 직원이 정규직원인지 파트타임인지 감지할 수 있습니다.

직원 객체는 작업 행위를 가지고 있다는 데서, 절차적 프로그램의 직원 레코드와는 다릅니다. 이 작업들은 아마도 객체의 데이터를 읽거나 변경하는데 사용될 겁니다. 객체는 자신의 등에 데이터를 메고 있는 작은 프로그램 처럼 동작합니다.


여러분이 어떤 것을 알고 싶거나, 어떤 일을 하기를 원한다면 객체에게 작업을 수행하도록 요청하면 됩니다. 이것을 객체지향 세계의 말로 "메세지" 보낸다 라고 합니다. 응답은 객체의 두번째 특성입니다.  직원 객체는 내장된 행위로 급여에 대해 어떻게 말해야 하는지, 우편물 주소 라벨을 어떻게 인쇄해야 하는지 알고 있을 것입니다.

객체의 세번째 특성은 유일한 아이덴티티를 가지고 있다는 것 입니다. 이것이 모든 객체가 관계형 데이터베이스에서 말하는 ID 값이나 Primary Key를 가져야 함을 의미하는 것은 아닙니다. 객체는 구조적 언어의 '변수'와 매우 닮았다고 할 수 있습니다. 정수 변수 i 와 j는 같은 값을 가질 수 있지만 여전히 구분 될 수 있습니다. 


클래스란 무었인가? What Are Classes?

자바 프로그램이 객체의 집합으로 이루어진다면, 대체 클래스란 뭘까? "학생" 객체의 집합인가? 아닙니다.
클래스는 객체 생성의 청사진 blueprint 입니다. 여러분은 실제 객체에 대한 코드를 절대로 작성할 수 없으며, 객체를 만드는데 사용되는 패턴을 작성할 수 있을 뿐입니다. 클래스와 객체의 구별하는 것은 미묘하지만 객체지향 디자인을 이해하기 위한 기본입니다.
 
클래스와 객체 사이의 관계를 이해하는 좋은 방법은 구조적 프로그래밍 언어의 '타입 Type' 과 '변수 Variable'를 떠올리면 됩니다. 변수의 타입을 이야기 할때 그 변수로 어떤작업을 할수 있는지, 저장할 수 있는 범위가 어떻게 되는지로 기술합니다. 예를 들어, 정수 변수는 복소수를 저장 할수 없습니다. 같은 방법으로 정수와 소수의 곱하기 연산은 가능하지만, 맞춤법 검사는 오로지 문자열에 대해서만 가능합니다.

변수는 값을 저장한다는데 주목하라 : 타입이 하는 일이 아닙니다. 타입은 추상이라고 말할 수 있습니다. 실제로 정수 값을 저장하려면 정수 변수를 생성해야만 합니다. 정수 타입으로 지정된 청사진으로 변수가 생성되면 그 변수는 정수입니다. 정수 타입에 결정된 규칙에 의해 저장되고, 행동합니다. 각각의 i,j,k 정수를 정수 타입의 '인스턴스'라고 말합니다.

객체와 클래스는 비슷한 관계를 가지고 있습니다. 클래스는 객체가 소유하게 될 속성 attributes 과 행위 behaviors 를 정의합니다. 클래스는 객체 생성의 청사진 blueprint 입니다. 자바 프로그램을 작성할 때 남이 작성한 클래스를 사용하기도 하고, 자신의 장치에 맞는 새로운 클래스를 정의하기도 합니다. 새로운 클래스를 생성하는 일은 두 부분으로 나누어져 있습니다. 

1. 객체의 상태를 저장하는데 사용될 속성을 정의 합니다.
2. 객체가 이해할 수 있는 메세지와 메세지에 응답하는 과정을 정의 합니다. 각각의 메세지에 대해 메소드 method 라고 불리우는 프로시저를 만들고, 이것을 구현합니다.


캡슐화란 무엇인가? What is Encapsulation?

객체,클래스와는 다르게 캡슐화는 자바 언어의 요소가 아닙니다. 캡슐화는 잘-설계된 클래스를 만드는데 사용되는 기법입니다. 잘-설계된 객체-지향 클래스는 캡슐화 기법을 요구합니다.

"좋아, 캡슐화라는 것에 기꺼이 주목할께, 하지만 마치 우주인이 가지고 있을 만한 물건처럼 들리는데, 도대체 그게 뭐야." 캡슐화는 프로그램을 포장 packaging 하는 작업입니다. 클래스는 두 부분으로 나눌 수 있습니다: 인터페이스 interface 와 구현 implementation.

"잠깐, 당신은 이미 클래스는 속성 attributes 과 메소드 methods 의 두-부분으로 구성되어 있다고 말했잖아요, 인터페이스와 구현은 속성과 메소드를 부르는 새로운 용어 인가요?" 라고 반응할 수 있습니다.

여러분의 객체는 속성과 메소드로 만들어져 있습니다. 일부 속성과 메소드는 객체의 외부에서 접근할 수 있고 이것을 인터페이스 interface 라고 합니다. 다른 속성,메소드는 객체 자신만의 사적인 용도로 예약되어 있고 이것을 구현 implement 이라고 합니다. 구현으로 부터 인터페이스를 분리하는 것은 객체-지향 프로그램을 설계할 때 가장 중요한 결정 입니다. 

구현으로 부터 인터페이스를 나누는 일의 가치를 살펴보자면, 자동차를 연상하면 쉬울 것입니다. 자동차의 인터페이스는  핸들, 가속 페달, 브레이크로 간단하고 규격화 되어 있습니다. 운전방법을 한번 배우기만 하면 됩니다. 반면에 자동차의 내부 동작은 점화, 실린더, 연료 분사 등등 매년 역동적으로 변경됩니다. 여러분이 각기 다른 타입의 자동차의 점화 시스템을 직접 통제해야 한다면, 새차를 운전하기란 매우 어렵다는 걸 알게 될겁니다. 

잘-설계된 클래스 Well-Designed Class 는 이런 특성을 가지고 있습니다. 인터페이스는 여러분의 클래스와 어떻게 상호작용 해야 하는지 완벽하게 묘사합니다. 그리고 클래스의 대부분의 속성은 감추어 진다는 것을 의미합니다. 사용자는 데이터를 수정하기 위해서 메소드를 사용할 것입니다.



상속이란 무엇인가? What Is Inheritance?

상속 계층을 구조화 하는 것은 클래스 설계의 두번째 결정입니다. 캡슐화는 변경으로 부터 클래스를 견고하게 만드는데 필요합니다. 상속은 클래스 관계에서 "가족 famillis" 개념과 연관이 있습니다.  

"상속의 진가는 강력한 추상 구조화 이다."

클래스의 상속관계를 정의하면 두가지의 큰 잇점을 얻을 수 있습니다. 새로운 종류의 서브클래스를 작성하면, 여려분은 부모 super class 에 이미 내장된 기능들을 사용할 수 있습니다. 이는 상속을 사용하는 가장 일반적인 잇점입니다. 그러나 이게 전부는 아닙니다. 프로그래밍 언어에서 프로시저가 처음 사용 될 때, 중복 코드를 줄이라고 요구합니다. 그리고, 복잡한 컴퓨터를 구성하고 정복하는 엄청난 힘이라는 것이 증명되었습니다.  상속의 진가는 추상화를 구조화 한다는데 있습니다. 프로시저는 복잡한 문제를 단순한 부분으로 나눌 수 있게 합니다. 상속을 사용하면 공통적인 요소를 슈퍼클래스에 정의 함으로써 일반화 할 수 있습니다. 

구조적 프로그래밍은 분해 decomposition (프로시저 형태로의 분해) 에 의한 추상화에 기반하고 있습니다. 객체-지향 프로그래밍은 추상 메커니즘을 이용해 추상화를 포함합니다. 클래스화 classification 에 의한 추상화를 기반으로 상속을 적용하는 메커니즘을 이용합니다. 자연과학에서 처럼 계층구조를 묘사할 수 있음이 계층적 클래스화의 힘입니다. 계층구조는 우리 행성의  수백만 종에 달하는 동,식물의 정보를 구조화하는 강력한 도구 입니다.


다형성이란 무엇인가? What Is Polymorphism?

마지막으로, 다형성은 객체-지향 프로그래밍의 기반 원칙입니다. "많은 형태 many shapes" 라는 뜻을 가진 그리스어에서 유래한 말로,
다형성은 캡슐화, 상속과 함께 작동해서 객체-지향 프로그램의 흐름 제어 flow of control 를 단순화 합니다.

"다형성은 캡슐화, 상속과 함께 동작 함으로써 객체-지향 프로그램의 흐름 제어를 단순화 합니다."

흐름 제어, 다음에 일어날 일을 알아햐 한다는 것은 컴퓨터 프로그램의 아킬레스 건 입니다. 이게 바로 프로그램이 복잡하게 되는 주요 원인입니다. 모든 경로를 추적하지 않고서는 객체가 가질 상태의 가능성을 검사 할 방법이 없습니다. 따라서 여러분은 프로그램을 테스트 하다가 지쳐 버릴 것입니다. 구조적 프로그래밍에서 프로그램의 흐름 제어를 단순화 하는 초기 시도는 조건 없는 분기로 규범화된 순서 구조, 선택, 반복을 제공하는 것 이었습니다. 같은 방법으로 다형성은 상속 계층의 연관된 객체에 메세지를 보냄으로써 단순화 합니다.

객체에 메세지를 보낼 때, 그 객체는 메세지에 응답할 메소드를 가지고 있어야 합니다. 클래스가 상속 계층에 연결되어 있다면, 모든 서브클래스는 부모의 인터페이스를 자동으로 상속 받습니다. 어떤 일이라도 슈퍼클래스 객체가 할 수 있는 것이라면 서브클래스 객체도 할 수 있습니다. 예를 들어, 클래스 A가 클래스 B의 서브클래스 라면, A 객체는 B객체가 할 수 있는 모든 일을 할 수 있습니다. A객체는 B객체라고 말할 수 있고, 이런 경우의 상속 관계를 ISA 관계 라고 부릅니다. 비록 서브클래스 객체가 슈퍼클래스 객체가 하는 것 처럼 동일한 메시지에 응답할 책임이 있다 하더라도, 메세지는 동일한 동작을 하도록 강제하지 않습니다. 이것을 이해할 필요가 있습니다. 각각의 서브클래스는 슈퍼클래스가 정의하고 있는 적절한 응답 또는 새로 정의된 특화된 응답에 의존하고 있습니다. 그래서, 각각의 서브클래스는 같은 메세지에 다른 응답을 할 수 있습니다. 이게 "많은 형태"라고 말하는 의미 입니다.


주 : 다음 동작에 대한 조건의 선택을 객체의 계층구조로 추상화 해 흐름 제어를 다형성으로 처리하는 구현 방법은 마틴 파울러의 리팩토링의 Replace Conditional with Polymorphism(293) 에 기술되어 있습니다.

다형성으로 조건문을 제거하라 Replace Conditional with Polymorphism(293)

객체 전문용어 가운데 가장 멋지게 들리는 말 중의 하나가 다형성(polymorphism)이다. 다형성의 진가는 동작이 그 타입에 따라 변하는 객체를 가지고 있을 때, 명시적으로 조건문을 사용하지 않아도 되도록 한다는 데 있다. 

리팩토링, 마틴 파울러 지음/윤성준,조재박 옮김, 대청, p.293 

Object-Oriented Design in Java, by Stephen Gilbert and Bill McCarty, Sams, 1998 p.32~43
 
### 끝.



저작자 표시
신고

이 글을 Twitter / Facebook 에 공유하기
이 글이 유익하다면 아래의 트위터 버튼을 눌러 공유해 주시거나, 페이스북 "좋아요" 버튼을 눌러 주세요.

   


Posted by 반더빌트
근래의 거의 모든 프로그래밍 객체지향이란 개념으로 구현합니다. 또한, 새롭게 제시되는 방법론 들도 모두 객체지향을 기반으로 제시됩니다. 실세계의 사물을 추상화(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' 이라는 값을 반환 합니다.

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


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

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

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


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


결론.


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

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


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

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

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

### 끝.


더 읽을 꺼리 :
제목 : 구조적 프로그래밍 이란?
http://user.chol.com/~hurcb01/study5_sub7.html
신고

이 글을 Twitter / Facebook 에 공유하기
이 글이 유익하다면 아래의 트위터 버튼을 눌러 공유해 주시거나, 페이스북 "좋아요" 버튼을 눌러 주세요.

   


Posted by 반더빌트


티스토리 툴바