소프트웨어 복잡성을 관리하려면 실제로 OO 언어가 필요합니까?


209

이것은 매우 기술적이지 않고 부드러운 질문이 될 것이며 이것이 올바른 플랫폼인지 확실하지 않습니다. 그러나 나는 CS 학생을 시작하여 여러분이 그것을 참기를 바랍니다.

첫 학기에는 Java 및 UML을 통해 캡슐화, 데이터 숨기기, 모듈화, 상속 등과 같은 OOP 개념을 소개했습니다. (자바는 나의 첫 프로그래밍 언어이다)

내가 이해하는 방식으로 OOP는 소프트웨어 복잡성을 관리하는 방법입니다. 그러나 그 원칙은 새롭거나 독창적이지 않으며 모든 엔지니어링 분야에 보편적으로 적용됩니다.

예를 들어 자동차는 복잡성이 잘 정의 된 동작 및 인터페이스를 가진 모듈 식 및 캡슐화 된 구성 요소의 계층 구조로 관리되는 매우 복잡한 구조입니다.

그러나 나는 새로운 프로그래밍 패러다임을 도입 한 이유를 이해하지 못한다. 복잡성을 관리하는 데 사용되는 모든 원칙은 절차 적 프로그래밍 언어로 실현할 수 있다고 생각합니다. 예를 들어 모듈성을 위해 프로그램을 별도의 파일에 포함 된 잘 정의 된 작업을 수행하는 여러 개의 작은 프로그램으로 나눌 수 있습니다. 이러한 프로그램은 잘 정의 된 입력 및 출력을 통해 서로 상호 작용합니다. 캡슐화를 위해 파일을 보호 (암호화) 할 수 있습니다. 코드 재사용을 위해 새 프로그램에서 필요할 때마다 해당 파일을 호출 할 수 있습니다. 이것이 OOP가 무엇인지 모두 포착하지 못합니까? 아니면 매우 분명한 것이 빠져 있습니까?

OOP가 복잡성을 관리한다는 증거를 요구하지 않습니다. 내 생각에 그것은 확실히 않습니다. 그러나 모듈성, 캡슐화, 데이터 숨기기 등과 같은 복잡성을 관리하는 데 사용되는 모든 원칙은 절차 적 언어로 쉽게 구현할 수 있다고 생각합니다. 복잡성없이 복잡성을 관리 할 수 ​​있다면 왜 OOP일까요?


41
인터페이스와 구현의 분리가 누락되었습니다. 런타임에 한 구현을 다른 구현으로 교체 할 수 있다는 것은 매우 중요한 기능입니다. 기본적으로 이것은 상속을 통해 OO 언어의 동적 메소드 디스패치에 의해 달성됩니다. 절차 적 언어도 친절 할 수 있지만 (읽기 : void 포인터) 유형 안전성이 없습니다.
marstato

81
대체로 객체 지향 언어와 디자인의 아이디어는 이러한 보편적이고 직관적 인 개념 을 가능한 한 쉽게 코드로 표현하고 재현 할 수 있도록하는 것입니다. 본질적으로 객체 지향 언어없이 모든 것을 달성하는 방법에 대한 계획이나 일련의 지침 이 있다면 작업 수행 방법에 대한 제안 은 효과적으로 객체 지향 방법론이 될 입니다. 실제 OO 언어는이를 공식화하고 단순화하는 방법 일뿐입니다.
Standback

14
@RobbieDee 실제로 내 질문을 읽었습니까? OO없이 소프트웨어 복잡성을 관리 할 수있는 날씨에 의문을 제기하여보다 근본적인 수준에서 OO를 이해하려고합니다. 나는 OO를 훼손하려고 시도하지 않고 새로운 것을 발명하려고 시도하지 않고 단지 그것을 더 잘 이해하려고 노력하고 있으며 질문이 너무 '자명 한'것이라면 왜 Jorg로부터 훌륭한 답변을 받았습니까?
steakexchange

12
파일 암호화는 캡슐화되지 않습니다. 다른 개발자가 코드의 내용을 보지 못할 수도 있지만 코드의 내부 작업을 다른 코드로부터 보호 할 필요는 없습니다. 원래 작성자는 암호화 방법 전후에이를 수행 할 수 있습니다.
JeffO

8
기계 언어 이외의 것은 필요 하지 않습니다 . 프로그래머가 opcode를 암기하고 직접 0과 0을 쓰도록하십시오. 그러나 일종의 "기호"언어를 갖는 것은 오류를 줄이고 생산성을 높이는 데 매우 유용하며 Dijkstra가 관찰 한 것처럼 일부 "구조"를 적용하는 언어 (또는 "구조"를보다 쉽게 ​​유지 관리하는 데 도움이되는 언어)가 상당히 도움이됩니다. OO 언어는 현재 수준의 언어 정교함을 감안할 때 이상적인 기술이 아닐 수 있지만 많은 응용 프로그램에 적합합니다. 아이디어는 방해받지 않고 복잡성을 관리하는 것입니다.
Daniel R Hicks

답변:


177

정말 낮은 이론 답변으로 시도하겠습니다 :)

실제로 요구하는 것은 절차 언어를 사용하여 OO 코드를 디자인하고 작성할 수있는 경우 언어에 직접 객체 지향 (OO)에 대한 지원을 포함시키는 이유는 무엇입니까?

답은 다음과 같습니다. OO가 소스 코드로 표현되는 방식에 대한 표준을 갖추기 때문에 동일한 추상화에 대해 22 가지의 다른 구현으로 끝나지 않습니다.

예를 들어, 사용자 인터페이스 시스템에서 사용할 수있는 a MagicButton및 a MagicSlider를 작성한다고 가정하겠습니다 . MagicButton과 함께 사용할 수있는 메서드, MagicSlider와 함께 만 사용할 수있는 메서드 및 두 가지가 모두 사용할 수있는 메서드를 그룹화하는 방법이 필요합니다. 이 객체들은 모두 Magic GUI 객체이기 때문에 몇 가지 방법을 공유합니다.

특별한 방법으로 MagicSlider_DoSomething ...명명 된 특정 파일에 메소드를 포함시켜 특별한 방법으로 함수의 이름을 지정하여 그룹화 MagicSliderMethods.XXX를 수행하거나 동일한 일을 수행하는 다른 특별한 방법을 찾을 수 있습니다. 언어에 표준 방법이 없다면 나는 그것을 당신과 다르게 할 것이고 다른 사람과 다르게 할 것입니다. 이로 인해 코드 공유가 훨씬 어려워집니다.

예, OO 언어의 가상 메소드 인 늦은 디스패치는 절차 적 언어로 구현할 수 있지만 구현 방법은 매우 다양합니다. 코드를 작성한 사람에 따라 동일한 프로그램 내에서 다른 OO 구현이 생길 수 있습니다.

유지 보수 개발자가 열악하다고 생각하십시오. 이 사람은 원래 코드를 작성한 사람에 따라 다른 객체 추상화와 가상 메서드를 호출하는 다양한 방법을 관리해야합니다.

또한 언어로 추상화하면 Eclipse와 같은 고급 코드 편집기에서 코드에 대한 많은 정적 분석을 수행 할 수 있습니다. 예를 들어, Eclipse는 빈 "TODO 메소드"의 자동 구현뿐만 아니라 오브젝트에서 사용할 수있는 모든 메소드 목록을 제공 할 수 있습니다. Eclispe는 어떤 클래스를 확장하고 어떤 인터페이스를 구현하는지에 따라 클래스가 구현해야하는 메소드를 정확히 알고 있습니다. OO를 수행 할 언어 표준이 없으면 거의 불가능합니다.


40
고전적인 예 : 루아. 기본적으로 OO는 아니지만 만들 수는 있지만 완전히 상호 운용성이없는 5 개의 다른 잘 알려진 OO 라이브러리가 있음을 의미합니다.
Kroltan

55
@steakexchange 당신은 절대에 너무 집중합니다. "단독 목적"이 거의 없습니다. 언어는 모두 다른 수준의 품질로 많은 일을합니다. 언어를 선택하는 것은 필요한 목적에 가장 적합한 절충 세트를 선택하는 것입니다.
Tim B

42
@nocomprende 추상화 표준화는 문자 그대로 프로그래밍 언어에 대한 것입니다. 어셈블리 언어조차도 10 년 반 동안 10 개의 하드웨어 세대와 같은 차이점을 추상화합니다.
David Moles

56
@DavidMoles 표준화 된 추상화 말 그대로 프로그래밍 언어입니다. 문자 그대로 "문자 그대로"를 사용할 수있는 완벽한 기회를 낭비하지 마십시오!
Clement Cherlin 23.01에

12
이것을 표준화하는 것이 가능하다. 제가 90 년대 중반에 일을했을 때, 저는 X-Windows에서 상당히 많은 양의 작업을했습니다 (주로 그러한 것들을 기억하는 사람들을 위해 Motif를 기반으로합니다). X-Windows는 실제로 객체 지향의 모든 기능을 일반 C 로 구현할 수있게 해주었 습니다 . 그렇게하는 정신 체조는 상당히 실질적이었고, 상자 안을 보지 않는 사람들에 크게 의존했습니다 (Schroedinger의 위젯 코드는 일반적으로 죽었습니다). OO 언어는 일반 컴파일러가 어셈블러에 사용하는 것과 같은 방식으로 코더에서이를 숨기고 인생이 더 쉽습니다.
Graham

211

첫 학기에는 Java 및 UML을 통해 캡슐화, 데이터 숨기기, 모듈화, 상속 등과 같은 OOP 개념을 소개했습니다. (자바는 나의 첫 프로그래밍 언어이다)

이들 중 어느 것도 OOP 개념이 아닙니다. 그것들은 모두 OO와 독립적으로 OO 외부에 존재하며 심지어 OO 이전에도 발명되었습니다.

그래서, 당신은 아니라고 생각하면 OO이, 모두에 대해 다음 결론은 옳은 일이다 : 당신은 절차 적 언어로 사람들의 모든 작업을 수행 할 수 있습니다 그들이 OO와는 아무 상관이 없기 때문에 .

예를 들어, 모듈성에 관한 주요 논문 중 하나는 시스템을 모듈로 분해하는 데 사용되는 기준 에 관한 것 입니다. 거기에 OO에 대한 언급이 없습니다. (이것은 1972 년에 쓰여졌으며 그때까지 OO는 이미 10 년이 넘었음에도 불구하고 여전히 모호한 틈새 시장이었습니다.)

하지만 데이터 추상화는 OO에서 중요하다, 그것은 더입니다 결과 가 결정적인 기능을보다 OO (메시징)의 주요 기능. 또한 서로 다른 종류 의 데이터 추상화 가 있다는 것을 기억하는 것이 매우 중요합니다 . 오늘날 사용되는 가장 일반적인 두 종류의 데이터 추상화는 (다른 두 가지 결합보다 여전히 사용되는 "추상화 없음"을 무시하는 경우) Abstract Data Types and Objects 입니다. 따라서 "Information Hiding", "Encapsulation"및 "Data Abstraction"이라고 말하면 OO는 데이터 추상화의 형태 뿐이며 두 가지가 근본적으로 다릅니다.

  • 추상 데이터 형식에서 추상화 메커니즘은 형식 시스템입니다 . 구현을 숨기는 타입 시스템입니다. 유형 시스템이 반드시 정적 일 필요는 없습니다. Objects를 사용하면 구현이 유형이 필요하지 않은 절차 적 인터페이스 뒤에 숨겨집니다 . 예를 들어 ECMAScript에서와 같이 클로저로 구현할 수 있습니다.
  • 추상 데이터 형식을 사용하면 서로 다른 ADT의 인스턴스가 서로 캡슐화되지만 동일한 ADT의 인스턴스는 서로의 표현 및 개인 구현을 검사하고 액세스 할 수 있습니다. 객체는 항상 모든 것에서 캡슐화됩니다 . 객체 자체 만 자체 표현을 검사하고 자체 구현에 액세스 할 수 있습니다. 다른 객체 , 같은 유형의 다른 객체, 같은 클래스의 다른 인스턴스, 동일한 프로토 타입을 가진 다른 객체, 객체의 복제본 등이 불가능합니다. 없음 .

이것이 의미하는 바는 Java에서 클래스는 객체 지향적이지 않다는 것입니다. 동일한 클래스의 두 인스턴스는 서로의 표현 및 개인 구현에 액세스 할 수 있습니다. 따라서 클래스의 인스턴스는 개체가 아니며 실제로 ADT 인스턴스입니다. 자바 interface의, 그러나 않는 객체 지향 데이터 추상화를 제공한다. 즉, 인터페이스의 인스턴스 만 Java의 객체이고 클래스의 인스턴스는 그렇지 않습니다.

기본적으로 유형의 경우 인터페이스 만 사용할 수 있습니다. 이는 매개 변수 유형의 메소드 및 생성자, 리턴 유형의 메소드, 인스턴스 필드 유형, 정적 필드 및 로컬 필드, instanceof연산자 또는 캐스트 연산자에 대한 인수 및 일반 유형 생성자에 대한 유형 인수는 항상 인터페이스 여야합니다. 클래스는 new연산자 바로 뒤에 만 사용할 수 있습니다 .

예를 들어 모듈성을 위해 프로그램을 별도의 파일에 포함 된 잘 정의 된 작업을 수행하는 여러 개의 작은 프로그램으로 나눌 수 있습니다. 이러한 프로그램은 잘 정의 된 입력 및 출력을 통해 서로 상호 작용합니다. 캡슐화를 위해 파일을 보호 (암호화) 할 수 있습니다. 코드 재사용을 위해 새 프로그램에서 필요할 때마다 해당 파일을 호출 할 수 있습니다. 이것이 OOP가 무엇인지 모두 포착하지 못합니까? 아니면 매우 분명한 것이 빠져 있습니까?

당신이 설명하는 것은 OO입니다.

그것은 실제로 OO를 생각하는 좋은 방법입니다. 사실, 그것은 OO의 최초 발명가들이 생각했던 것과 거의 똑같습니다. (Alan Kay는 한 걸음 더 나아갔습니다. 그는 네트워크를 통해 서로에게 메시지를 보내는 많은 작은 컴퓨터를 구상했습니다.) "프로그램"이라고하는 것은 일반적으로 "개체"라고하며 "통화"대신 일반적으로 "메시지 보내기"라고 말합니다. ".

객체 지향은 메시징 (일명 동적 디스패치 )에 관한 것입니다. "객체 지향"이라는 용어는 스몰 토크의 수석 디자이너 인 Alan Kay 박사가 만든 것으로 다음과 같이 정의합니다 .

나에게 OOP는 메시징, 로컬 보존 및 상태 프로세스 숨기기 및 모든 것의 늦게 바인딩을 의미합니다.

그것을 분해하자 :

  • 메시징 (Smalltalk에 익숙하지 않은 경우 "가상 메소드 디스패치")
  • 상태 프로세스는
    • 국부적으로 보유
    • 보호
    • 숨겨진
  • 모든 것의 극단적 인 구속력

구현 현명한, 메시징은 런타임에 바인딩 된 프로 시저 호출, 그리고 프로 시저 호출은 런타임에 바인딩하는 경우, 당신은 디자인 타임에 알 수없는 어떤 전화 할거야, 그래서 당신은 국가의 구체적인 표현에 대한 가정을 만들 수 없습니다. 따라서 실제로 메시징에 관한 것입니다. 후기 바인딩은 메시징의 구현이며 캡슐화는 그 결과입니다.

그는 나중에 " 큰 아이디어는 '메시징' "이라고 설명하고 "개체 지향"이라는 용어가 중요하지 않은 것에 중점을두기 때문에 "메시지 지향"대신 "개체 지향"이라고 불렀습니다. ) 및 실제로 중요한 사항 (메시지)을 산만하게합니다.

마지막 OOPSLA에서 스몰 토크가 구문이나 클래스 라이브러리뿐만 아니라 클래스에 관한 것도 아니라는 사실을 모든 사람들에게 상기시키기 위해 약간의 고통을 겪었다는 것을 상기시켜줍니다. 오래 전에이 주제에 대해 "개체"라는 용어를 만들어서 유감스럽게 생각합니다.

큰 아이디어는 "메시징 (messaging)"입니다. 이것이 스몰 토크 / 스 퀘이크의 핵심이되는 것입니다 (그리고 우리의 제록스 PARC 단계에서 결코 완성되지 않은 것입니다). 일본인은 "가장 중간에있는"이라는 단어가 작습니다. 아마도 가장 가까운 영어 단어는 "삽입 광고"입니다. 훌륭하고 확장 가능한 시스템을 만드는 데있어 핵심은 내부 속성과 동작이 아닌 모듈이 통신하는 방식을 디자인하는 것보다 훨씬 더 중요합니다. 인터넷을 생각하십시오. 살기 위해서는 (a) 단일 표준을 넘어서는 많은 다른 종류의 아이디어와 실현을 허용해야하고 (b) 이러한 아이디어들간에 다양한 정도의 안전한 상호 운용성을 허용해야합니다.

(물론 오늘날 대부분의 사람들은 사물에 초점을 맞추지 않고 수업에 집중합니다.

메시지는 은유 및 메커니즘으로 OO의 기본 입니다.

누군가에게 메시지를 보내면 상대방이하는 일을 알 수 없습니다. 관찰 할 수 있는 유일한 것은 그들의 반응입니다. 메시지 자체를 처리했는지 (예 : 객체에 메소드가있는 경우), 메시지를 다른 사람에게 전달한 경우 (위임 / 프록시) 모르는 경우 알 수 없습니다. 그것이 캡슐화의 모든 것입니다. 그것이 OO의 모든 것입니다. 프록시가 예상대로 응답하는 한 프록시를 실제와 구별 할 수 없습니다.

"메시징"에 대한 "현대적인"용어는 "동적 메소드 디스패치"또는 "가상 메소드 호출"이지만 은유를 잃고 메커니즘에 중점을 둡니다.

따라서 Alan Kay의 정의를 보는 두 가지 방법이 있습니다. 독자적으로보고있는 경우 메시징은 기본적으로 지연된 프로 시저 호출이고 지연 바인딩은 캡슐화를 의미하므로 # 1을 결론 지을 수 있습니다. # 2는 실제로 중복되며 OO는 늦게 바인딩됩니다.

그러나 나중에 중요한 것은 메시징이라는 점을 명확하게 밝혔으므로 다른 관점에서 볼 수 있습니다. 메시징은 지연됩니다. 이제 메시징이 유일 하게 가능하다면 # 3은 사실 일 것입니다. 단 하나만 있고 그 것이 늦으면 모든 것이 늦습니다. 그리고 다시 한 번 캡슐화는 메시징에서 따릅니다.

윌리엄 R. 쿡 (William R. Cook)이 재검토On Understanding Data Abstraction 에서도 비슷한 점을 지적 하고 있으며 "개체"와 "개체 지향"에 대한 단순화 된 현대적 정의에 대한 그의 제안 :

작업의 동적 디스패치는 객체의 필수 특성입니다. 이는 호출되는 조작이 오브젝트 자체의 동적 특성임을 의미합니다. 오퍼레이션은 정적으로 식별 될 수 없으며, 일반적으로 오퍼레이션을 실행하는 것을 제외하고는 주어진 요청에 응답하여 어떤 오퍼레이션이 실행 될지 정확히 알 수있는 방법이 없습니다. 이것은 항상 동적으로 전달되는 일급 함수와 동일합니다.

스몰 토크 -72에는 아무 물체도 없었습니다! 파싱, 재 작성 및 재 라우팅 된 메시지 스트림 있었습니다 . 처음에는 메소드 (메시지 스트림을 구문 분석하고 다시 라우팅하는 표준 방법)가 왔으며 나중에 오브젝트 (일부 개인 상태를 공유하는 메소드 그룹)가 나왔습니다. 상속은 훨씬 후에 왔으며 상속을 지원하는 방법으로 만 수업이 도입되었습니다. Kay의 리서치 그룹이 이미 프로토 타입에 대해 알고 있었다면 아마도 처음에는 수업을 소개하지 않았을 것입니다.

유형 및 프로그래밍 언어의 Benjamin Pierce 는 객체 지향의 정의 기능이 Open Recursion 이라고 주장합니다 .

Alan Kay에 따르면 OO는 메시징에 관한 것입니다. William Cook에 따르면, OO는 동적 메소드 디스패치 (실제로 동일한 것)에 관한 것입니다. 벤자민 피어스 (Benjamin Pierce)에 따르면, OO는 Open Recursion에 관한 것입니다. 이는 기본적으로 자체 참조가 동적으로 해결되거나 (또는 ​​적어도 생각하는 방식 임), 즉 메시징입니다.

보시다시피, "OO"라는 용어를 만든 사람은 대상에 대해 다소 형이상학 적 관점을 가지고 있고, Cook은 다소 실용적 관점을 가지고 있으며, 매우 엄격한 수학적 관점을 관통합니다. 그러나 중요한 것은 철학자, 실용 주의자 및 이론가가 모두 동의한다는 것입니다! 메시징은 OO의 한 축입니다. 기간.

상속에 대한 언급은 없습니다! OO에는 상속이 반드시 필요한 것은 아닙니다. 일반적으로 대부분의 OO 언어에는 구현 재사용 방법이 있지만 반드시 상속 할 필요는 없습니다. 예를 들어 어떤 형태의 위임 일 수도 있습니다. 실제로, 올랜도 조약은 상속에 대한 대안으로서 위임 을 논의 하고, 다른 형태의 위임과 상속이 어떻게 객체 지향 언어의 디자인 공간 내에서 다른 디자인 포인트로 이어지는 지 논의합니다. (실제로 Java와 같은 상속을 지원하는 언어에서도 사람들은 실제로 그것을 피하도록 지시 받았으며 다시 OO에 필요하지 않음을 나타냅니다.)


16
+100-사물이 부적절하게 사용되어 사물에 고유 한 책임이 있습니다.
JeffO

55
죄송하지만 이건 정말 잘못되었습니다. 앨런 케이 (Alan Kay)는이 용어를 생각해 냈을 수도 있지만 스몰 토크 이전에는 원칙이있었습니다. 객체 지향 프로그래밍은 Simula에서 파생되었으며 OO 스타일은 "메시지"와 관련이 없습니다. 성공한 거의 모든 OO 언어는 우리가 Java에서 볼 수있는 것과 동일한 Simula에 설정된 기본 원칙에 따라 실행되었으며 Smalltalk 스타일의 OO는 다시 도입 될 때마다 "아이디어 마켓 플레이스"에서 실패했습니다. 전혀 잘 작동하지 않기 때문입니다. 케이가 기여한 유일한 의미있는 이름이었습니다 .
메이슨 휠러

23
@steakexchange No. "OO의 본질"은 진정으로 독특하게 만드는 것은 가상 방법을 가진 객체입니다. 스몰 토크를 사용하지 않는 이유는 다음과 같습니다. 메시지 전달 시스템은 개별 컴퓨터 규모에서 매우 잘 작동하지 않습니다. 의도가 많지만 순진한 언어 디자이너가 스몰 토크 원칙을 다시 구현하려고 할 때마다 실패합니다. (가장 최근의 사례는 Objective-C인데, Steve Jobs가 iOS 커뮤니티 전체의 목을 쓰러 뜨리지 않았다면 아무도 사용하지 않았을 것입니다. Apple 에코 시스템 외부에서 어떤 견인차도 찾지 못했기 때문에 그 이유가 있습니다. )
메이슨 휠러

28
@ MasonWheeler Jorg의 말과 반대되는 견해를 가지고 있기 때문에 답변에 대한 귀하의 의견을 자세히 설명해 주시겠습니까?
steakexchange

20
객체 지향 언어의 개념이 많이 발전했다는 점도 주목할 가치가 있습니다. 이러한 조상 개념은 오늘날 구 모델을 버리고 다중 패러다임을 수용하는 많은 언어에서 오늘날처럼 사실이 아닐 수도 있습니다. 예를 들어 C #을보십시오. 언어는 태양 아래에서 거의 모든 것을 한 번에 혼합하며 대부분 OO 언어라고하지만 실제로는 다른 패러다임의 혼합입니다. 이를 통해 모든 개발자가 실제로 표현할 수있는 도구가 될 수 있습니다. 또한 클래스 기반 OO는 유효한 OO 프로그래밍의 여러 가지 특징 중 하나입니다.
T. Sar

66

그러나 모듈성, 캡슐화, 데이터 숨기기 등과 같은 복잡성을 관리하는 데 사용되는 모든 원칙은 절차 적 언어로 쉽게 구현할 수 있다고 생각합니다.

"매우 쉽게"말할 때 매우 대담한 진술을하는 것입니다. 내가 읽는 방식은 다음과 같습니다. "난이도는 보이지 않으므로 매우 크지 않아야합니다." 그런 식으로 말하면 "왜 우리는 OO가 필요합니까?"라고 묻지 않는 것이 분명해집니다. OO의 발명을 이끌어내는 다른 프로그래밍 패러다임이 어려움을 겪지 않는 이유는 무엇입니까? "

이 질문에 대한 답은 이러한 어려움 중 많은 부분이 현재 진행중인 프로그램 종류에 존재하지 않는다는 것입니다. 40 년 된 스파게티 코드를 업데이트하라는 메시지가 표시되지 않습니다. 운영 체제에 대한 새 디스플레이 관리자를 쓰려고하지 않습니다. 다중 스레드 분산 응용 프로그램을 디버깅하지 않습니다.

우리 CS 학생들이 작문을해야하는 많은 종류의 장난감 프로그램들에 대해, 우리는 BASIC 또는 Java 또는 Python과 같은 어셈블리로 작성하는 것도 가능합니다. 이는 작업의 고유 한 복잡성이 매우 낮기 때문에 개발자가 한 명 뿐이며 레거시 상호 운용성 문제가 없으며 성능은 중요하지 않으며 코드는 한 컴퓨터에서 몇 번만 실행될 것입니다.

학생 운전사를 데리고 급한 시간에 혼잡 한 언덕으로 향하는 신 크롬이없는 수동 변속기에서 바쁜 거리에 합류하라고 요구한다고 상상해보십시오. 재앙. 왜? 작업에 필요한 모든 규칙을 동시에 따르는 데 필요한 복잡성 수준을 관리 할 수 ​​없습니다.

이제 같은 학생, 같은 차량, 빈 주차장에서 걷는 속도로 운전한다고 상상해보십시오. 그들은 기술 수준이 작업에 적합하기 때문에 괜찮습니다. 압력, 위험이 거의 없으며 시작, 클러치, 변속, 가속, 조향의 개별 하위 작업을 한 번에 하나씩 수행 할 수 있습니다.

숙련 된 운전자가이 모든 작업을 동시에 수행 할 수 있다면 학생이 자동 변속기가있는 이유를 물을 수 있습니까? 정답은 충분한 운전자가 최적의 조건에서 자동을 필요로하지 않는다는 것입니다. 그러나 우리는 최고 상태의 모든 전문 운전자가 아니며, 일반적으로 자동차 디자이너가 우리를 위해 모든 복잡성을 처리하게하는 편리함을 원합니다.

숙련되고 숙련 된 충분한 프로그래머는 실제로 C 또는 어셈블리에서 작동하는 고 복잡도 시스템을 만들 수 있습니다. 그러나 우리는 모두 리누스 토발즈가 아닙니다. 또한 유용한 소프트웨어를 만들 필요도 없습니다.

나는 개인적으로 현대 언어의 모든 기능을 재발견하여 관심있는 문제를 해결하기 전에 관심이 없습니다. 이미 해결 된 문제에 대한 솔루션이 포함 된 언어를 활용할 수 있다면 왜 그렇지 않습니까?

따라서 언어가 캡슐화 및 다형성과 같은 편리한 기능을 제공하는지 물어보고 왜 사용하지 않습니까?


13
기본적으로 절차 언어로 OO를 수행 할 수 있지만 표준화 된 OO 언어를 사용하여 자동화하고 단순화하는 동안 수동으로 작업을 수행합니다.
steakexchange

6
@steakexchange 정확히 그렇습니다.
Tim B

3
@steakexchange 역사적으로 좋은 예는 X Windows의 개체 모델이었습니다. C로 작성되었지만 객체 지향 시스템을 기반으로합니다. 그래서, 당신은 당신의 수업이 다른 사람들과 잘 어울릴 수 있도록 특정 규칙을 따라야했습니다.
Ukko

7
@nocomprende 확실히. 그러나 하나 있습니다 기록 원시 디스크을하는 대신 파일 시스템에 의존하여 부팅 한 컴퓨터 렌더링, 거기 것이다 초보자에 의해 구축 된 임시 객체 시스템 디버그 문제에 대한 진정한 어려울 수. 캡슐화는 올바르게 수행 될 때 의도적으로 또는 실수로하지 말아야 할 일을 방해하지 않도록합니다.
Clement Cherlin

3
OO로 혜택을 볼 수있는 응용 프로그램의 예가 종종 OO 언어로 작성되지 않은 것이 흥미 롭습니다. 40 세의 스파게티는 C, COBOL, FORTRAN 또는 REXX로 작성되었을 것입니다. 디스플레이 관리자는 C로 작성되었지만 (OO-ish 규칙에도 불구하고) 성공적인 분산 멀티 스레드 시스템은 Erlang, Go 또는 C로 작성됩니다.
James_pic

22

당신이 설명하는 것은 OOP가 아니며 추상화입니다. 추상화는 OOP가 아닌 모든 최신 디자인 모델에 존재합니다. 그리고 OOP는 매우 특정한 종류의 추상화입니다.

첫째, OOP에 대한 단일 정의가 없다는 점에 주목할 가치가 있으므로 내가 OOP로 특성화하는 것에 동의하지 않는 사람들이있을 수 있습니다.

둘째, OOP는 전통적인 디자인 모델에서 영감을 얻었으므로 자동차 디자인과의 유사성은 우연의 일치가 아닙니다.

그러나 OOP가 당신이 말한 것보다 더 미묘한 방법이 있습니다.

  • 캡슐화 : 모듈에 대한 설정된 인터페이스 (예 : 추상화)가 아니라이 인터페이스 이외의 액세스를 금지하는 것입니다. Java에서 개인 변수에 액세스하는 것은 컴파일 오류이지만 자동차 디자인에서는 의도 한 인터페이스와 다른 방식으로 사물을 사용할 수 있습니다.

  • 상속 : 이 정말 OOP 고유 만드는 일이다. 인터페이스를 정의한 후에는 해당 인터페이스를 구현하는 여러 가지 작업을 수행 할 수 있으며 구현의 특정 부분을 변경하면서 이전의 모든 부분 을 상속 하여 코드 중복을 크게 줄이면서 계층 구조로이를 수행 할 수 있습니다 .

    자동차의 캡슐화 된 구성 요소로 생각하면 실제로 이와 동등한 것은 아닙니다. 다른 기어를 가져 와서 구현의 특정 부분을 변경하여 기어를 만들 수있는 방법이 없습니다. (적어도 나는 그렇게 생각하지 않는다. 나는 차에 대해 많이 모른다.)

  • 다형성 : 인터페이스를 정의한 후에는 사용 가능한 작업의 관점에서 해당 인터페이스를 사용하는 항목을 구분할 수 없어야하며 인터페이스를 사용하기 위해 어떤 구현이 사용되고 있는지 알 필요가 없습니다. 여기에서 서브 타이핑Liskov 대체 원칙 이 중요해집니다.

  • 커플 링 : OOP의 주요 측면은 동일한 작업과 사물을 밀접하게 연관시키고 다양한 형태를 분산시킬 수 있다는 것입니다. 데이터는 해당 데이터에 대한 작업과 번들로 제공됩니다. 즉, 새로운 형식의 데이터 (새 구현)를 추가하는 것은 매우 쉽지만 인터페이스에 새 작업을 추가하는 것은 매우 어렵습니다 (인터페이스를 구현하는 각 클래스를 업데이트해야하기 때문). 이는 기능 언어의 대수 데이터 유형과 대조적으로 새로운 작업을 추가하는 것이 매우 쉽고 (모든 경우를 처리하는 함수를 작성하기 만 함) 새로운 변형을 추가하기는 어렵습니다 (새로 추가해야하기 때문에) 모든 기능에 대한 사례).


1
좋은 대답입니다! 내가 동의하지 않는 한 부분 : 캡슐화에 대해 그리는 구별이 유효하지 않습니다. 캡슐화는 항상 "이 인터페이스 이외의 액세스 금지"를 의미합니다. 이는 OOP 및 비 OOP 설정 모두에 해당됩니다. 따라서이 부분은 실제로 OOP에 고유 한 것이 아닙니다.
DW

@DW OOP 고유의 것이 아니라 캡슐화와 추상화의 차이점이라고 말하면서 이것을 명확히하려고 노력했습니다. 피드백 주셔서 감사합니다!
jmite

2
승인. 그러나 나는 여전히 그 주제에 관해 여기에 쓰여진 것에 대해 다른 견해를 가지고 있습니다. "OOP가 말한 것보다 더 미묘한 차이가있다"고 썼지 만 캡슐화는 OOP가 질문에 쓰여진 것보다 더 미묘한 차이가 아닙니다. 캡슐화는 어떤 패러다임에서도 그대로입니다. 그리고 당신이 "당신이 묘사하는 것은 OOP가 아니며 추상화입니다"라고 쓴 곳에서, 나는 원래의 질문이 캡슐화를 설명하려고 노력하고 있다고 생각했습니다 (추상화가 아니라). 이 의견을 다른 관점으로 남겨 두겠습니다. 나는 대답이 매우 도움이된다고 생각합니다!
DW

상속은 일반적인 기능이지만 몇 가지 중요한 OO 언어에는 부족합니다.
Bradd Szonye

좋은 대답이지만 IMO는 자동차 예제를 과장하고 있습니다. 특정 모델의 엔진에는 잘 정의 된 인터페이스 (캠 샤프트, 장착 브래킷 "리셉터클"등)가 있습니다. 변속기에 영향을주지 않고 일반 오래된 기화기를 연료 분사식 기화기로 교체하거나 터보 차저 등 추가 할 수 있습니다. (디젤 엔진에는 수정 된 연료 탱크 IIRC가 필요하지만) 수동 변속기는 엔진에 전혀 영향을 미치지 않는 자동 및 AFAIK로 교체 할 수 있습니다.
David

11

소프트웨어 복잡성을 관리하려면 실제로 OO 언어가 필요합니까?

이것은 "필요하다"라는 단어의 의미에 달려 있습니다.

"필요"가 요구하는 것을 요구하는 경우, 우리는 요구하지 않습니다.

"필요"가 "강력한 혜택 제공"을 의미하는 경우 "예"라고 말하고 싶습니다.

큰 그림

OO 언어는 기능을 데이터에 바인딩합니다.

이 바인딩을 피하고 데이터 값을 전달하는 함수를 작성할 수 있습니다.

그러나 아마도 당신은 아마도 합쳐지는 데이터의 별자리에 휩싸 일 것이고, 당신은 튜플, 레코드 또는 데이터의 사전을 통과하기 시작할 것입니다.

그리고 실제로 모든 메소드 호출은 다음과 같습니다. 바인딩 된 데이터 세트에 대한 부분 함수.

기능별 기능

OOP의 특징 :

  • 상속 은 코드 (믹스 인)와 개념 (추상 기본 클래스 / 인터페이스) 재사용을 허용하지만 하위 범위에서 함수와 변수를 다시 꾸미면 얻을 수 있습니다.
  • 캡슐화를 통해 정보를 숨길 수 있으므로 더 높은 수준의 추상화에서 작업 할 수 있지만 헤더 파일, 함수 및 모듈을 사용하여이를 수행 할 수 있습니다.
  • 다형성 (polymorphism) 은 인자가 동일한 인터페이스를 지원하는 한 다른 유형의 인자를 사용할 수있게하지만 함수를 통해서도 그렇게 할 수 있습니다.

그러나 이러한 기능을 일류로 지원하는 객체 지향 언어와 같이 쉬운 일은 없습니다.

참고 문헌

OOP에 대한 많은 비평가가 있습니다.

그러나 연구에 따르면 코드 재사용에서 OOP를 통해 프로그래머 생산성이 향상되는 것으로 나타났습니다. 이것은 논란의 여지가있는 결과이며 일부 연구자들은 특정 제약 조건에서 이러한 생산성 향상을 재현 할 수 없다고 말합니다. (출처)

결론

우리는 OOP를 "필요"하지 않습니다. 그러나 어떤 경우에는 사용자 OOP를 원합니다 .

성숙한 프로그래머는 객체 지향 스타일에서 상당히 생산적이라는 것을 이해합니다. 패키지에 쉽게 이해할 수있는 간단한 인터페이스를 가진 핵심 객체가있는 경우 새로운 프로그래머라도 빠르게 생산성을 높일 수 있습니다.


10

간략하게 노력하겠습니다.

OO의 핵심 원칙은 단일 조직 단위 (객체)에서 데이터와 행동의 조합입니다.

이것이 우리가 복잡성을 통제 할 수있게 해주 며 그것이 등장했을 때 매우 혁신적인 개념이었습니다. 한편으로는 파일 (순수한 데이터), 다른 한편으로는 해당 파일을 읽고 처리하는 프로그램 (순수한 논리) 및 출력 (순수한 데이터)을 비교하십시오.

실제 실체를 모델링 한 데이터와 로직 패키지를 한 번만 가지고 나면 메시지 교환을 시작하고, 자식 클래스를 만들고, 공개 데이터와 동작과 개인을 분리하고, 다형성 동작을 구현하고,이 모든 OO 관련 마법을 수행 할 수 있습니다.

예, OO는 큰 문제입니다. 그리고 아니, 그것은 멋진 이름을 가진 단지 오래된 것들이 아닙니다.

모든 것을 분리하고 요소를 살펴본 후 "오, 여기에 보지 못한 것은 없습니다"라고 말하는 것은 혁신을 유지하는 회의를 인정하지 않습니다. 결과는 부품의 합보다 큽니다.


8

객체 지향 프로그래밍에 대한 "공식적인"정의는 없으며, 합리적인 사람들은 실제로 OO의 품질을 정의하는 것에 동의하지 않습니다. 일부는 메시징, 일부는 하위 유형, 일부는 상속, 일부는 데이터와 행동의 번들이라고 말합니다. 그렇다고해서 그 용어가 의미가 없다는 것을 의미하는 것은 아니며, 실제 OO가 무엇인지에 대해 너무 신경 써서는 안됩니다 .

캡슐화와 모듈성은 디자인의 기본 원칙이며 모든 프로그래밍 패러다임에 적용되어야합니다. OO의 지지자들은 이러한 속성들이 OO를 통해서만 달성 될 수 있다고 주장하지 않으며 OO가이를 달성하는 데 특히 적합하다고 주장합니다. 물론 함수형 프로그래밍과 같은 다른 패러다임의 지지자들은 그들의 패러다임에 대해서도 같은 주장을합니다. 실제로 많은 성공적인 언어는 다중 패러다임이며 OO, 기능 등은 "하나의 진정한 방법"이 아닌 도구로 보여야합니다.

복잡성을 관리하는 데 사용되는 모든 원칙은 절차 적 프로그래밍 언어로 실현할 수 있다고 생각합니다.

결국 모든 프로그래밍 언어로 무엇이든 할 수 있기 때문에 사실입니다. 모든 언어의 강점과 약점이 있기 때문에 일부 언어에서는 다른 언어보다 쉬울 수 있습니다.


7

다른 답변에서 언급하지 않은 것 : state.

복잡성 을 관리하기위한 도구로 OO에 대해 이야기 합니다. 복잡성은 무엇입니까? 그것은 희미한 용어입니다. 우리 모두는 그것이 의미하는 바에 대해이 gestalt 감각을 가지고 있지만 그것을 고정시키기는 더 어렵습니다. 우리는 순환 복잡성, 즉 코드를 통한 런타임 경로 수를 측정 할 수 있지만 복잡성을 관리하기 위해 OO를 사용할 때 이것이 무엇인지에 대해 알지 못합니다.

내가 생각하는 우리가 이야기하고있는 것은 국가와 관련된 복잡성이다.

캡슐화 에는 두 가지 주요 아이디어가 있습니다 . 그중 하나는 구현 세부 사항을 숨기고 다른 답변에서 꽤 잘 설명 되어 있습니다. 그러나 다른 하나는 런타임 상태를 숨기고 있습니다. 우리는 객체의 내부 데이터를 다루지 않습니다. 우리는 메시지를 전달합니다 (또는 Jörg Mittag가 지적한 개념보다 구현 세부 사항을 선호하는 경우 메소드를 호출하십시오). 왜?

사람들은 이미 코드를 변경하지 않고 데이터의 내부 구조를 변경할 수 없기 때문에 300 개 장소 대신 한 곳에서 (액세스 방법) 그렇게하고 싶어하기 때문에 이미 언급했습니다.

그러나 그것은 또한 코드 가 추론하기 어렵게하기 때문입니다 : 절차 적 코드 (자연적으로 절차 적이거나 언어로 작성된 언어에 관계없이)는 국가의 돌연변이에 제한을 가하는 데 거의 도움이되지 않습니다. 언제 어디서나 무엇이든 바꿀 수 있습니다. 호출 함수 / 메소드에는 거리에서 짜증나는 행동이있을 수 있습니다. 테스트의 성공 여부는 광범위하게 액세스 / 액세스 가능한 로컬 변수가 아닌 값에 따라 결정되므로 자동화 된 테스트는 더 어렵습니다.

다른 두 개의 큰 프로그래밍 패러다임 (OO 및 기능)은 상태 관련 복잡성 문제에 대한 흥미롭지 만 거의 정반대되는 솔루션을 제공합니다. 함수형 프로그래밍에서는이를 피하려고합니다. 함수는 일반적으로 순수하고 데이터 구조에 대한 작업은 원본을 제자리에 업데이트하지 않고 복사본을 반환합니다.

반면 OO는 상태 관리 를 처리 하는 도구 (상태 방지 도구 대신)를 제공합니다. 액세스 수정 자 (보호 / 공개 / 개인), 게터 및 세터 등과 같은 언어 수준 도구 외에도 개체를 통해 다른 개체 데이터를 가져 오는 것을 방지하는 데 도움이되는 Demeter of Law와 같은 여러 관련 규칙이 있습니다. .

실제로이 작업 을 수행하기 위해 객체가 필요 하지 않습니다 . 데이터에 액세스 할 수없고 데이터를 조작하는 함수의 데이터 구조를 반환하는 클로저가있을 수 있습니다. 그러나 그것은 객체가 아닌가? 그것은 객체가 무엇인지에 대한 우리의 개념에 맞지 않습니까? 그리고 만약 우리가이 개념을 가지고 있다면, 경쟁하는 임시 구현의 조합 폭발에 의존하는 것보다 (다른 답변에서 말했듯이) 언어로 개념을 재조정하는 것이 낫지 않습니까?


5

소프트웨어 복잡성을 관리하려면 실제로 OO 언어가 필요합니까?

아니요. 그러나 많은 상황에서 도움을 줄 수 있습니다.

나는 주로 수십 년 동안 단일 OO 언어를 사용했지만 대부분의 코드는 실제로 엄격하게 pre-OO 스타일 절차입니다. 그러나 GUI와 관련된 모든 것에는 언어의 방대한 내장 메소드 및 객체의 OO 라이브러리가 사용됩니다. 코드가 엄청나게 단순 해지기 때문입니다.

예를 들어, 원래의 하위 수준 Windows API를 사용하여 양식, 단추 및 편집 필드를 표시하는 Windows 응용 프로그램에는 많은 코드가 필요하지만 대신 Visual Basic, C # 또는 Delphi와 함께 제공되는 개체 라이브러리를 사용하면 작고 사소한 프로그램. 따라서 내 OO 코드는 일반적으로 상대적으로 작고 GUI에 비해 해당 객체가 호출하는 코드는 일반적으로 훨씬 크고 일반적으로 OO와 관련이 없습니다 (해결하려는 문제에 따라 다를 수 있음).

나는 너무 복잡하고 객체가 어떻게 구현되었는지에 대한 복잡한 난해한 규칙에 의존하는 OO 프로그램을 보았으며 OO 개념없이 작성하면 훨씬 간단 해졌습니다. 나는 또한 반대를 보았습니다. 복잡한 시스템은 객체를 사용하여 다시 구현되고 단순화되기를 원합니다.

경험을 쌓으면서 서로 다른 상황에 따라 다른 도구와 솔루션이 필요하며 한 가지 크기만으로는 맞지 않을 수 있습니다.


3

C로 작성된 매우 큰 프로젝트에 참여한 누군가로서 나는 그 대답이 분명한“아니오”라고 말할 수 있습니다.

모듈성이 중요합니다. 그러나 모듈화는 거의 모든 언어로 구현할 수 있습니다. 예를 들어 C는 모듈 식 컴파일, 헤더 파일 및 구조 유형을 지원합니다. 99 %의 경우 충분합니다. 필요한 새 추상 데이터 유형마다 모듈을 정의하고 데이터 유형에서 작동하기위한 기능을 정의하십시오. 때로는 성능을 원하고 해당 함수가 헤더 파일에 인라인 함수로 있으며 다른 경우에는 표준 함수를 사용합니다. 어떤 방법을 선택했는지는 사용자에게 보이지 않습니다.

구조는 구성을 지원합니다. 예를 들어, 뮤텍스 잠금과 일반 해시 테이블로 구성된 잠긴 해시 테이블을 가질 수 있습니다. 이것은 객체 지향 프로그래밍이 아닙니다. 서브 클래 싱이 수행되지 않습니다. 구성은 객체 지향 프로그래밍의 아이디어보다 훨씬 오래된 도구입니다.

컴파일 수준 모듈성이 충분하지 않고 런타임 모듈성이 필요한 경우의 1 %에 대해 함수 포인터라는 것이 있습니다. 잘 정의 된 인터페이스를 개별적으로 구현할 수 있습니다. 이것은 객체 지향이 아닌 언어의 객체 지향 프로그래밍이 아닙니다. 이것은 인터페이스를 정의한 다음 구현하는 것입니다. 예를 들어, 서브 클래 싱은 여기에서 사용되지 않습니다.

아마도 가장 복잡한 오픈 소스 프로젝트를 생각해보십시오. 즉, 리눅스 커널. 전적으로 C 언어로 작성되었습니다. 주로 컴포지션을 포함한 표준 컴파일 수준 모듈화 도구를 사용하여 수행되며, 때로는 런타임 모듈화가 필요할 때마다 함수 포인터를 사용하여 인터페이스를 정의하고 구현합니다.

Linux 커널에서 객체 지향 프로그래밍의 예를 찾으려면 "인터페이스 정의 및 구현"과 같은 표준 작업을 포함하도록 객체 지향 프로그래밍을 확장하지 않는 한 이러한 예를 찾는 것이 매우 어렵다고 확신합니다.

C 프로그래밍 언어조차도 실제로 필요한 경우 객체 지향 프로그래밍을 지원합니다. 예를 들어 GTK 그래픽 사용자 인터페이스 툴킷을 고려하십시오. 비 객체 지향 언어로 작성되었지만 실제로 객체 지향입니다. 따라서 이것은 "객체 지향 언어"가 필요하다는 생각에 깊은 결함이 있음을 보여줍니다. 다른 종류의 언어로는 할 수없는 객체 지향 언어는 할 수있는 것이 없습니다. 또한 전문 프로그래머라면 어떤 언어로도 객체 지향 코드를 작성하는 방법을 매우 쉽게 알 수 있습니다. 예를 들어 C를 사용하는 것은 부담이 아닙니다.

따라서 객체 지향 언어는 개념이 실제로 어떻게 구현되는지 이해하지 못하는 초보 프로그래머에게만 유용 할 것입니다. 그러나 프로그래머가 그런 초보자 프로그래머 인 프로젝트 근처에 있고 싶지 않습니다.


1
"[...] 결론은 객체 지향 언어는 개념이 실제로 어떻게 구현되는지 이해하지 못하는 초보자 프로그래머에게만 유용 할 것입니다." 흥미 롭군 어떤 언어를 염두에두고 있습니까? 이러한 언어로 작성된 오픈 소스 프로젝트에 실패했거나 실패하지 않은 예가 있습니까?
Vincent Savard

3
당신은 몇 가지 좋은 점을 제기하지만 주요 아이디어에는 결함이 있습니다. 예, C와 같은 언어로 캡슐화, 가상 디스패치, 상속 및 가비지 수집과 같은 OO 개념을 구현할 수 있습니다. 또한 어셈블리에서이를 수행 할 수도 있습니다. 프로그래밍이 더 쉬워지지는 않습니다. C와 같은 언어로 프로그래밍하고 특히 디자인하는 것은 OO 언어보다 훨씬 어렵습니다. C에서는 개념을 구현에 맵핑해야하며, OO 언어에서는 해당 단계를 수행 할 필요가 없습니다 (적어도 OO 개념에는 해당되지 않음).
fishinear

1
"[함수 포인터]를 사용하면 잘 정의 된 인터페이스를 개별적으로 구현할 수 있습니다. 이는 객체 지향이 아닌 언어의 객체 지향 프로그래밍이 아닙니다. 이는 인터페이스를 정의한 다음 구현하는 것입니다." 죄송하지만, 이것은 OOP 와 정확히 일치 하므로 완전히 잘못되었습니다 . "예를 들어, 여기에서 서브 클래 싱은 사용되지 않습니다"서브 클래 싱은 OOP의 필수 기능이 아닙니다. 예를 들어, JavaScript는 서브 클래 싱을 특징으로하지 않는 객체 지향 언어입니다.
Jules

1
마지막 의견을 명확히하기 위해 필자의 요점은 OOP (특정 OO 언어는 아님)와 다른 방법의 주요 구별 요소는 OOP에서 데이터 형식을 알 필요없이 데이터에서 추상적으로 작동하는 인터페이스를 정의한다는 것입니다. 인터페이스 구현을 데이터 자체에 바인딩 그것이 OOP입니다. 구현 방법은 Java 스타일 클래스, JavaScript 객체 (실제로 이름에 대한 속성 맵, 데이터 또는 코드 일 수 있음) 또는 함수 포인터 및 데이터에 대한 void *를 포함하는 구조에 관계없이 관련이 없습니다.
Jules

1
"따라서, 객체 지향 언어는 개념이 실제로 어떻게 구현되는지 이해하지 못하는 초보 프로그래머에게만 유용 할 것입니다.".... 솔직히 이것은 모욕적입니다. 이러한 개념이 어떻게 구현되는지 충분히 알고 있습니다. 그때까지도 능숙 해지기 위해 충분한 노력을 기울였습니다. 과거에는 OO 언어에 대한 인터프리터와 컴파일러를 모두 구현했습니다. 그러나 일급 객체가있는 고급 언어로 작업하는 것을 선호하기 때문에 함께 일하지 않는 초보자 프로그래머 여야합니까?!
Jules

2

객체 지향 방법을 포함한 프로그래밍 패러다임을 도입하는 이유는보다 정교하고 강력한 프로그램을보다 쉽게 ​​만들 수 있기 때문입니다. Byte Magazine의 1981 년 8 월호에서 Smalltalk의 주요 제작자 중 한 명인 Daniel Ingalls 는 다음과 같은 기능을 포함하는 것으로 "객체 지향"을 정의했습니다.

  • 자동 스토리지 관리
  • 메시지 교환 능력
  • 언어의 모든 작업에 적용되는 균일 한 은유
  • 다른 구성 요소의 내부에 의존하는 구성 요소가 없습니다 (모듈성)
  • 프로그램은 표현이 아닌 객체의 행동 만 정의합니다 (다형성)
  • 각 구성 요소는 한 곳에만 나타나야합니다 (인수 분해)
  • 하드웨어 독립적 인 가상 머신 사용
  • 모든 사용자가 접근 할 수있는 구성 요소는 관찰 및 제어가 가능해야합니다 (반응 원리).
  • 전체 컨트롤러가 없어야합니다 (운영 체제 없음).

이것이 Ingalls가 Xerox Parc Research에서 개발 한 SmallTalk-80의 구동 설계 고려 사항으로 확인 된 원칙입니다. 앞서 언급 한 잡지 기사에서 이러한 각 원칙에 대한 자세한 설명과 이러한 원칙이 Ingalls에 따른 객체 지향 패러다임에 어떻게 기여하는지 읽을 수 있습니다.

이러한 모든 원칙은 절차 적 언어, 조립 언어 또는 기타 모든 Turing 완전한 언어를 사용하여 적용 할 수 있습니다. 이것들은 언어 사양이 아닌 디자인 원칙입니다. 객체 지향 언어는 소프트웨어를 만들 때 이러한 원칙을보다 쉽게 ​​사용할 수 있도록하기위한 것입니다.

예를 들어, Ingall의 첫 번째 원칙 (자동 스토리지 관리)을 취하기 위해 누구나 절차 적 언어로 자신의 자동 스토리지 관리 시스템을 작성할 수 있지만 그렇게하려면 많은 작업이 필요합니다. 자동 스토리지 관리 기능이 내장 된 SmallTalk 또는 Java와 같은 언어를 사용하는 경우 프로그래머는 메모리 관리 작업을 많이 수행 할 필요가 없습니다. 트레이드 오프는 프로그래머가 메모리 사용 방식을 덜 제어한다는 것입니다. 따라서 이점과 단점이 있습니다. 객체 지향 프로그래밍과 같은 디자인 패러다임의 아이디어는 패러다임의 이점이 최소한 일부 프로그래머에게는 단점보다 크다는 것입니다.


도메인 특정 언어의 경우에도 동일한 규칙이 적용될 것이라고 생각합니다. 동일한 장점과 단점 ... 한 가지 차이점은 '언어'가 문제 공간에 대한 이해에 해당하고 다른 것은 포함되어 있지 않기 때문에 최종 사용자가 작업 할 수 있도록 DSL을 간단하게 만들 수 있다는 것입니다.

0

소프트웨어 복잡성을 관리하는 한 가지 방법은 도메인 특정 언어를 사용하여 프레임 워크를 원하는 작업과 완전히 분리하는 것 입니다. 이것은 프로그래밍 코드의 수준이 원하는 결과가 구성되는 수준 (완전히 다른 언어 또는 시스템)과 다르다는 것을 의미합니다. 이것이 올바르게 수행되면, 종래의 코드는 본질적으로 라이브러리가되고, 원하는 결과를 생성하는 사용자 또는 다른 사람은 스크립트 생성기 또는 보고서 생성기와 같은 시각적 디자인 도구와 함께 것들을 연결한다.

이를 위해서는 가능한 오퍼레이션과 링크 방식 (양식 구성 도구와 같은 스크립트 언어 또는 시각적 디자인)에 대해 엄격한 경계를 설정해야합니다. 메타 데이터는 코딩 세부 사항에서 런타임 구성을 추상화하는 중요한 방법이므로 시스템이 원하는 범위의 광범위한 결과를 지원할 수 있습니다. 경계가 정해져 있고 (확장에 대한 모든 요청을 받아들이지 않음), 사람들이 원하는 것을 성취하기 위해 프로그래머가 될 필요없이 오래 지속되는 강력한 시스템을 가질 수 있습니다.

마틴 파울러 (Martin Fowler)는 이것에 관한 책을 저술했으며이 기술은 프로그래밍만큼 오래되었습니다. 모든 프로그래밍 언어가 도메인 특정 언어라고 말할 수 있으므로 아이디어는 매우 명확하기 때문에 간과됩니다. 그러나 자신의 스크립팅 또는 시각적 디자인 도구를 만들어 생활을보다 쉽게 ​​만들 수 있습니다. 때때로 문제를 일반화하면 훨씬 쉽게 해결할 수 있습니다!


0

이것은 매우 좋은 질문이며 여기에 주어진 답변이 정의를 얻지 못했다고 생각하므로 계속해서 생각을 추가하겠습니다.

목표는 소프트웨어 복잡성 관리 입니다. 목표는 "OO 언어 사용"이 아닙니다.

새로운 패러다임을 도입 할 이유는 없습니다. 코딩이 성숙해지면서 자연스럽게 일어난 일입니다. 링크 된 목록의 끝에 새 노드를 추가하는 대신 기차의 끝에 코치를 추가하는 코드 (링크 된 목록을 사용하여 모델링 된 기차)를 작성하는 것이 더 합리적입니다.


실제 개체의 관점에서 코딩 단순히 우리가 때 코드에 분명하고 정확한 방법입니다 되는 현실 세계의 실체에 대해 코딩.


컴퓨터는 기차 끝에 추가 코치를 추가하는 것처럼 쉽게 링크 된 목록의 끝에 노드를 추가하는 작업을 수행 할 수 있습니다. 그러나 인간의 경우, 레벨이 깊어지면 링크 된 목록을 통해 기차가 모델링되는 것을 발견하더라도 링크 된 목록 및 노드를 사용하는 것보다 기차와 코치를 사용하는 것이 더 쉽습니다.

파일을 보호하거나 암호화하면 캡슐화를 수행 할 수 없습니다. 암호화의 반대는 해독입니다. 캡슐화의 반대는 Decapsulation입니다. 이는 더 나은 성능을 달성하기 위해 프로그래밍 언어에서 구조와 클래스를 분해 하는 것을 의미 합니다. 메모리 트래픽을 줄이고 OOP 규칙 확인을 피함으로써 성능이 향상되었습니다.

따라서이 두 가지 개념이 다르기 때문에 암호화되고 캡슐화 된 코드를 작성할 수 있습니다.

캡슐화는 현실에 가깝기 때문에 복잡성을 관리하는 데 도움이됩니다.

따라서 객체로 프로그래밍하면 코딩하기가 쉽고 사용자와 다른 사람들이 더 빨리 이해할 수 있기 때문입니다.


0

기억해야 할 것은 이것입니다.
OOP는 언어 기능에 관한 것이 아닙니다. 코드를 구성하는 방식에 관한 것입니다 .

OOP는 생각하고 코드 아키텍처를 설계하는 방법이며 거의 모든 언어로 수행 할 수 있습니다. 여기에는 특히 어셈블러 및 C라고하는 저수준 비 OO 언어가 포함됩니다. 어셈블러에서 완벽하게 객체 지향 프로그래밍을 수행 할 수 있으며 C로 작성된 Linux 커널은 여러 측면에서 상당히 객체 지향적입니다. .

즉, 언어의 OO 기능은 원하는 결과를 얻기 위해 작성해야하는 상용구 코드의 양을 크게 줄 입니다. 가상 함수 테이블을 명시 적으로 정의하고 C의 적절한 함수 포인터로 채워야하는 경우 Java에서는 아무 것도 수행하지 않고 완료됩니다. OO 언어는 단순히 소스 코드에서 부수고를 제거하여 클래스, 메소드, 멤버, 기본 클래스, 암시 적 생성자 / 소멸자 호출 등과 같은 멋진 언어 수준 추상화 뒤에 숨어 있습니다.

따라서 OOP를 수행하기 위해 OO 언어가 필요 하지 않습니다 . OOP가 괜찮은 OO 언어로 처리하기가 훨씬 쉽다 는 것입니다.


-1

객체 지향 프로그래밍은 단순한 모듈 + 캡슐화 이상입니다. 당신이 말했듯이, 모듈 + 캡슐화를 객체가 아닌 (프로 시저) 언어로 사용할 수 있습니다. OOP에는 그 이상의 것이 포함됩니다. 객체와 메소드가 관련됩니다. 따라서 OOP를 캡처하지 않습니다. https://en.wikipedia.org/wiki/Object-oriented_programming 또는 OOP에 대한 좋은 교과서 소개를 참조하십시오 .


답변 감사합니다. 하나를 추천 해 주시겠습니까?
steakexchange

-2

가장 큰 이유는 프로그램이 복잡 해짐에 따라 프로그램의 일부를 다른 부분에서 보이지 않게해야하거나, 앱의 복잡성과 기능의 수가 두뇌를 귀에서 빠지게 할 수 있기 때문입니다.

각각 약 20 개의 작업을 수행 할 수있는 100 개의 클래스로 구성된 시스템을 상상해 봅시다. 그것은 2,000 개의 기능입니다. 그러나 그 중 500 개만이 '저장'및 '삭제'와 같은 완전한 작업이며 1500은 약간의 유지 관리를 수행하거나 유틸리티 역할을 수행하는 내부 기능입니다. 치다;

// intentionally in a non-specific language!

setName(person, name) {
    nameParts = splitPersonName(name);
    person.firstName = nameParts[0];
    person.lastName = nameParts[1];
    person.modified = true;
}

splitPersonName(name) {
    var result = [];
    result.add(name.substring(0, name.indexOf(" ")));
    result.add(name.substring(name.indexOf(" ") + 1));
    return result;
}

그래서 SetName사람들이 일을해야 함수 한 사람 만 SplitPersonName사용하는 유틸리티 함수 에 의해 사람.

직접 절차 프로그래밍은이 두 작업을 구분하지 않습니다. 즉, 2,000 명의 기능이 모두주의를 끌기 위해 경쟁하는 것을 의미합니다. 그러나 이러한 기능을 '개인 기록이있는 모든 사람에게 사용 가능'으로 표시하고 '개인 기록 내부에서 유틸리티 기능으로 만 사용'으로 표시 할 수있는 경우 이제는 '모든 사람이 사용할 수있는'기능과 15 개의 '유틸리티'가 500입니다. 편집중인 수업에 대한 기능.

그 무엇 publicprivate할;

public class Person {
    public void setName(...) {...}
    private string[] splitPersonName(...) { ...}
}

1
내 질문을 올바르게 이해했는지 확실하지 않습니다. 복잡성을 관리하는 방법으로 캡슐화 및 데이터 숨기기를 이미 알고 있습니다. 나는 내부 프로그램이 별도의 보호 된 소스로 지정된 잘 정의 된 간단한 작업을 수행하는 모듈로 프로그램을 나누어서 절차 언어로 쉽게 수행 할 수 있다고 생각합니다. 그렇다면 절차 적 언어로 그러한 일을 할 수있을 때 왜 OOP입니까? 그게 내 질문입니다.
steakexchange

2
내 대답은 당신이 이런 종류의 일을하고 싶다면 특별한 툴링과 언어 구조를 작성해야한다는 것입니다 (예를 들어, 포함 할 수없는 하나의 파일에 대한 특별한 'include'호출) 다른 곳에 포함). 그 길을 시작한 후에는 실제로 객체 지향 언어를 자신의 방식으로 구현하기 시작했습니다. 예를 들어, C ++은 원래 일반 C를 생성 한 전 처리기 였으며 , 일단 시스템을 구현 한 후에는 C 위에 C ++과 매우 비슷해 보입니다.
user62575

3
@steakexchange OOP는 많은 절차 언어에 이와 같은 모듈 이 없었던 시기에 개발되었습니다 . 어떤 사람들은 그런 언어를 절차 적이라고 부르지 않을 것입니다. 실제로, 절차 적 언어가 OO이거나 그 반대가되어서는 안된다는 말은 없습니다. 라벨에주의하십시오. 라벨이 쉽게 오인 될 수 있습니다. 절차 적 언어가 공공 및 개인 분야 및 절차가있는 모듈을 지원하는 경우 다음과 같은 이점이 있습니다. "전통적인 절차"와 "OOP"의 주요 차이점은 OOP에서보다 유연하게 통화 발송이 가능하다는 것입니다. 실제로 엄격한 OOP에서는 결코 당신이 부르는 코드를 알 수 없습니다.
Luaan

2
@steakexchange ML 계열 언어에서 모듈은 훌륭하게 작동하며 람다와 결합하여 모든 OO 언어의 모든 기능을 제공합니다 (결국 함수는 단일 메소드와의 인터페이스입니다-거의 권장하지 않습니다) OO의 "좋은 코드"들? : P). 여러 가지 이유로, 그들은 C ++ 또는 Java와 같은보다 절차 적 언어보다 여전히 덜 사용되지만 호소력이 있으며 많은 사람들이 삶을 단순화 할 수있는 방법에 대해 사람들에게 교육하려고 노력하고 있습니다 (성공 여부).
Luaan

C는 이런 것들을 효과적으로 가지고 있습니다. 인터페이스 (.h 파일)가있는 모듈 (.c 파일)이 있으며 공용 (extern) 및 비 공용 (extern) 메소드 (함수)를 가질 수 있습니다. 함수 포인터 배열을 사용하여 가난한 사람의 다형성을 가질 수도 있습니다. OO가 C (또는 어쩌면 제정신)에서는 쉽다는 말은 아니지만 캡슐화가 매우 쉽습니다.
Nick Keighley
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.