왜 OOP가 어려운가요? [닫은]


91

객체 지향 언어 (Java)를 사용하기 시작했을 때, 나는 거의 "Cool"으로 가서 코딩을 시작했습니다. OOP에 대한 많은 질문을 읽은 후에야 최근까지만 생각해 본 적이 없습니다. 내가 얻는 일반적인 인상은 사람들이 어려움을 겪고 있다는 것입니다. 나는 그것을 어렵게 생각하지 않았고 어떤 천재라고도 말하지 않았기 때문에 무언가를 놓치거나 오해했을 것이라고 생각합니다.

OOP를 이해하기 어려운 이유는 무엇입니까? 인가 가 이해하기 어려운?


72
나는 반박한다 : 이해하기 어렵지 않고, 단지 마스터하기 어렵다. 전체적으로 프로그래밍하는 것이이 방법입니다.
Steven Evers

2
음? 어쩌면 프로그램을 할 수없는 프로그래머는 코드 라인 대신 oops를 탓하는 것이 어렵다는 것을 알 수 있습니까? 나는 모른다. 그러나 나는 누군가가 이해하기 어렵다고 말하는 것을 결코 들어 본 적이 없다. 그러나 ppl은 특히 변수의 값을 변경할 수 없으므로 기능이 이상하다고 말합니다.

5
@ acidzombie42 : 기능은 전혀 이상하지 않습니다. RAM의 위치를 ​​나타내는 변수의 내용을 변경하기 위해 명령 목록을 작성할 필요가 없습니다. 변수는 값을 나타내며 값을 변경하지 않습니다. 42는 42를 유지하고 x는 x를 유지합니다 – x가 무엇이든간에. 매개 변수에서 결과로 맵핑되는 함수를 작성합니다. 값은 숫자, 값 목록, 값에서 값으로의 함수, 부작용을 일으키는 프로그램 및 실행시 결과 값 등입니다. 그렇게하면 메인 함수의 결과는 컴파일러, 즉 실행할 수있는 프로그램에 의해 계산됩니다.
comonad

5
최근에 Haskell을 배우고 있습니다. 함수형 프로그래밍에 대해 더 많이 배우고 이해할수록 OOP가 더 어렵다고 생각합니다. 이것의 주된 이유는 OOP가 데이터 (객체 / 클래스)와 그에 작동하는 함수 (메서드)를 함께 묶으려고하기 때문입니다. 이것이 문제의 원인이며 많은 OOP 디자인 패턴이 데이터와 기능을 함께 묶지 않도록 고안되었습니다. 예를 들어, 팩토리 패턴은 생성자 (함수)를 작동중인 실제 객체와 구분하는 데 사용됩니다.
ming_codes

1
이름이 잘못 되었기 때문입니다. 대상은 동작 (동사)을 수행하고 객체는 동작을 수신한다는 점에서 주제 지향 프로그래밍이어야합니다. 따라서 johnsBall.throw ()는 실제로 의미가 없습니다.
Chris Cudmore

답변:


119

개인적으로 OOP의 역학을 이해하기가 상당히 쉽다는 것을 알았습니다. 나를위한 어려운 부분은 그것의 "왜"였습니다. 내가 처음 노출되었을 때 문제를 찾는 해결책처럼 보였습니다. 대부분의 사람들이 어려움을 겪고 있다고 생각하는 이유는 다음과 같습니다.

  1. 처음부터 OO를 가르치는 IMHO는 끔찍한 생각입니다. 절차 적 코딩은 "나쁜 습관"이 아니며 일부 작업에 적합한 도구입니다. OO 프로그램의 개별 메소드는 어쨌든 절차 상으로 보이는 경향이 있습니다. 더욱이, 절차 적 프로그래밍을 잘 배우기 전에 한계가 드러나기 전에, OO는 학생에게 그다지 유용하지 않은 것 같습니다.

  2. OO를 실제로 파악하기 전에 데이터 구조의 기본 사항과 후기 바인딩 / 고차 함수를 알아야합니다. 프리미티브를 사용하고 고차 함수를 전달하는 대신 데이터 구조화 개념을 이해하지 못하면 다형성 (기본적으로 데이터에 대한 포인터와 데이터에서 작동하는 많은 함수를 전달 함)을 파악하기가 어렵습니다. 함수를 가리키는 포인터.

  3. 디자인 패턴은 좀 더 발전된 것이 아니라 OO의 기본으로 가르쳐야합니다. 디자인 패턴을 사용하면 나무를 통해 숲을 볼 수 있으며 OO가 실제 문제를 단순화 할 수있는 위치에 대한 구체적인 예를 제공 할 수 있으며 결국에는이를 배우고 싶을 것입니다. 또한 일단 OO를 얻으면 대부분의 디자인 패턴이 뒤늦게 분명해집니다.


5
멋진 답변, 특히 번호 # 1. 물론 OO의 메소드는 절차 적 랭의 메소드처럼 보이지만 이제는 상태가있는 객체에 들어 있습니다.
Dan Rosenstark

3
나는 특히 당신의 첫 번째와 세 번째 포인트를 좋아합니다. 제 친구는 디자인 패턴을 좋아합니다. 좋은 OOP 만 사용하면 대부분 초기 문제에서 매우 자연스럽게 파생된다고 계속 말합니다.
CodexArcanum

7
"나에게 어려운 부분은"그것의 이유 "였습니다. 언어의 기본 (캡슐화)과 디자인 원칙 및 리팩토링 방법을 공통 솔루션 (디자인 패턴)에 대해 이해하고 적용하는 데 약간의 시간과 노력이 필요합니다.
Belun

12
본인은 # 1에 동의합니다. 제가 배우고있을 때보 다 절차 적으로 프로그래밍하는 방법을 이미 알고있는 사람들에게 OO를 설명하는 데 더 나은 일을해야한다는 경고에 동의합니다. 아니요, Cat에서 상속받은 클래스 에 대해 이야기하고 Mammal절차 적으로 작성한 실제 프로그램의 실제 예제를 사용하는 것은 유용하거나 유익하지 않습니다 . 간단한 데이터 구조처럼.
Carson63000

4
-1 오늘날 디자인 패턴이 너무 강조됩니다. 그것들은 중요하지만 확실합니다 : 첫째, 모든 패러다임에 중요합니다 : 기능적, 구조적, OO; 둘째, 패러다임의 일부가 아니며 다른 많은 사람들처럼 편리한 부가 기능입니다. @SoftwareRockstar는 이에 대한 답을 잘 설명합니다.
CesarGon

56

아직 언급되지 않은 몇 가지 요소가 있다고 생각합니다.

우선 모든 것이 대상인 "순수한 OOP"(예 : 스몰 토크)에서 숫자를 하나의 지능적인 대상으로 생각하기 위해 마음을 다소 부 자연스러운 구성으로 바꿔야합니다. 실제로는 가치 일 뿐이므로 21실제로 가치 일뿐입니다. 이는 OOP의 큰 장점이 현실을 더욱 밀접하게 모델링한다고 들었을 때 특히 문제가됩니다. 현실.

둘째, OOP의 상속은 대부분의 사람들의 정신 모델을 따르지 않습니다. 대부분의 사람들에게 가장 구체적으로 분류하는 것은 작동하는 클래스 계층을 만드는 데 필요한 절대 규칙에 가까운 곳 이 없습니다 . 특히, class D다른 class B것을 상속받는 것을 만드는 것은 class D공유 객체가의 모든 특성을 긍정적 으로 공유 한다는 것을 의미합니다 class B. class D새롭고 다양한 특성을 추가 할 수 있지만 모든 특성은 class B그대로 유지해야합니다.

반면에 사람들이 사물을 정신적으로 분류 할 때는 일반적으로 훨씬 느슨한 모델을 따릅니다. 예를 들어, 사람이 객체 클래스를 구성하는 것에 대한 규칙을 만들면 다른 규칙을 충분히 따르는 한 거의 모든 규칙을 위반할 수 있습니다. 실제로 깨질 수없는 몇 가지 규칙조차도 거의 항상 "스트레치"될 수 있습니다.

예를 들어, "car"를 클래스로 고려하십시오. 그것은 있는지 아주 쉽게 광대 한 대부분의 사람들은 "차"로 생각하는 것의 대부분은 네 개의 바퀴가 있습니다. 그러나 대부분의 사람들은 바퀴가 3 개인 자동차를 보았습니다 (적어도 그림). 올바른 나이의 우리 중 몇몇은 또한 6 개의 바퀴가 달린 80 년대 초반의 경주 용 자동차를 기억합니다. 이것은 기본적으로 우리에게 세 가지 선택을 남깁니다.

  1. 자동차에 몇 개의 바퀴가 있는지에 대해서는 아무 것도 주장하지 마십시오. 그러나 이것은 항상 4가 될 것이라는 암시 적 가정과 다른 숫자로 인해 깨질 수있는 코드로 이어질 수 있습니다.
  2. 모든 자동차에는 4 개의 바퀴가 있으며, 실제로는 알고 있지만 다른 자동차를 "차가 아닌"것으로 분류하십시오.
  3. 만일의 경우에도이 기능이 절대로 필요하지 않거나, 사용되거나, 제대로 테스트되지 않을 경우를 대비하여, 휠 수의 변화를 허용하도록 클래스를 설계하십시오.

OOP에 대한 교육은 종종 거대한 분류 체계를 구축하는 데 중점을 둡니다. 예를 들어 지구상의 모든 알려진 생명체의 거대한 계층 구조 또는 그 순서에 대한 거대한 계층 구조의 조각과 조각. 이로 인해 두 가지 문제가 발생합니다. 무엇보다 많은 사람들이 당면한 질문과 전혀 관련이없는 방대한 양의 정보에 집중하는 경향이 있습니다. 어느 시점에서 나는 개 품종을 모델링하는 방법과 (예를 들어) "미니어처 푸들"이 "풀 사이즈 푸들"에서 상속되어야하는지 또는 그 반대인지, 추상적 기반 "푸들"이 있어야하는지에 대해 다소 긴 토론을 보았습니다. "클래스 푸들"과 "미니어처 푸들"이 모두 포함 된 클래스. 그들이 모두 무시한 것처럼 보이는 것은 응용 프로그램이 개에 대한 라이센스를 추적해야한다는 것입니다.

둘째, 그리고 가장 중요한 것은 현재 작업에 중요한 특성에 중점을 두지 않고 항목의 특성에 중점을 둡니다. 실제로 필요한 부분을 모델링하는 데 중점을두고 있으며, 실제로 필요한 부분은 우리의 요구를 충족시킬 가장 간단한 모델을 구축하고 추상화를 사용하여 필요한 하위 클래스에 맞게 생성하여 추상화에 맞 춥니 다.

마지막으로 다시 한 번 말씀 드리겠습니다. 우리는 수년에 걸쳐 데이터베이스와 동일한 경로를 천천히 따르고 있습니다. 초기 데이터베이스는 계층 적 모델을 따랐습니다. 데이터에만 초점을 맞추는 것 외에 이것은 단일 상속입니다. 짧은 시간 동안, 몇 개의 데이터베이스가 네트워크 모델을 따랐습니다. 본질적으로 다중 상속과 동일합니다 (이 각도에서 볼 때, 여러 인터페이스는 여러 기본 클래스와 충분히 다르거 나주의를 기울여야합니다).

그러나 오래 전에 데이터베이스는 대부분 관계형 모델에 수렴되었습니다 (그리고 SQL이 아니더라도이 추상화 수준에서 현재 "NoSQL"데이터베이스도 관계형입니다). 관계형 모델의 장점은 여기서 반복하지 않을 것이라는 충분히 잘 알려져 있습니다. 우리가 프로그래밍 할 때 가장 가까운 관계형 모델의 아날로그는 일반 프로그래밍입니다 (죄송하지만 이름에도 불구하고 Java generics는 예를 들어 실제로 작은 단계이지만 자격이 없습니다) 올바른 방향으로).


매우 잘 말하면, 특히 OOP에 대한 대부분의 문제는 초보자가 이해하는 데 문제가 아니라 대부분의 OOP 프로그래머가 일반적으로 생각하는 것을 배우는 OOP 문제입니다. 나는 최근에 구성 요소 모델이 잘 작동하는 게임 디자인을 작업 해 왔는데, 이는 계층 적이 아니라 관계형 모델의 개념과 밀접한 관련이 있습니다.
CodexArcanum

7
며칠 전에 이것에 대해 생각하고있었습니다. OOP에서 읽은 첫 번째 학습 자료가 모두 상속에 중점을 둔 것처럼 보였지만, 내 경험에 따르면 상속은 해롭지 않더라도 대부분 쓸모가 없다고 나옵니다.
rmac

테이블 지향 프로그래밍 과 비슷 하지만 OOP가 소프트웨어 개발의 총알이 아니라는 것을 더 많이 깨닫게 될 것입니다.
OnesimusUnbound

1
@OnesimusUnbound : 차이점은 일반적인 프로그래밍은 실제로 무언가를 수행하는 실제적인 방법이며, 테이블 지향 프로그래밍은 주로 작동 방식에 대한 이론에 대한 미치광이의 열망입니다. '내가 무엇을 의미하는지 알 수 있습니다. 실제로 게시물은 모두 오래되지 않았을 수도 있습니다.
Jerry Coffin

3
그렇기 때문에 인터페이스가 너무 좋습니다. 상속 모델링을 가져 와서 br-thth-first 접근 방식으로 뒤집습니다. 예를 들어, 개 예에서 모든 개는 특정 품종에 대해 속과 최대 2 개의 슈퍼 종 (각 부모 당 하나씩)이 있다고 가정 할 수 있습니다. 특성이 포함 된 목록 속성도있을 수 있지만 가능한 다양성으로 인해 특성을 명확한 구조로 만들 수 있습니다. 특성을 크롤링하고 해당 결과를 기반으로 유사한 품종을 결합하기 위해 상세 검색을 구현하는 것이 좋습니다.
Evan Plaice

26

OOP는 추상적 사고 능력이 필요합니다. 전문 프로그래머조차도 거의 가지고 있지 않은 선물 / 저주.


35
모든 프로그래밍은 추상적입니다.
JeffO

28
@ Jeff O-동의하지 않습니다. 프로그래밍은 누군가에게 단계별로 무언가를하는 방법을 알려줄 수있는 능력 만 필요합니다. 땅콩 버터와 젤리 샌드위치 만드는 법을 누군가에게 말할 수 있다면 프로그래밍 인터페이스에 명령을 입력 할 수 있습니다. 이것은 ap, b & j 샌드위치를 ​​추상적으로 모델링하는 것과 완전히 다른 기술과 완전히 다른 기술입니다.
존 크래프트

16
누군가에게 연필 2 개를 건네주고 연필 1 개를 건네주고 얼마나 많은 연필이 있는지 묻는 것은 구체적입니다. 2 + 1 = 3은 추상입니다.
JeffO

17
나는 Jeff에 동의합니다. 프로그래밍은 기본적으로 되어 추상화를 관리 할 수 있습니다. 최소한 그것은 가장 기본적인 프로그램 흐름을 제외하고는 사실입니다 (다른 모든 것은 추상화없이 너무 복잡하기 때문입니다). 초보자가 추상화를 제어하는 ​​방법을 배울 때 프로그래밍 학습에는 뚜렷한 단계가 있습니다. 레시피는 유가 떨어지는 곳입니다. 프로그래밍없는 것도 요리와 같은 개별 알고리즘 레시피에 비유 될 수 있지만, 프로그래밍 격리 알고리즘을 구현하여 근본적으로 다른 것이다.
Konrad Rudolph

2
@KonradRudolph 좋은 지적입니다. +1은 "다른 모든 추상화없이 너무 복잡 할 것입니다" .
Karthik Sreenivasan

21

다음과 같이 기본적인 어려움을 요약 할 수 있다고 생각합니다.

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

물론, 사람들은 "왼쪽"을 270으로 매핑하는 데 익숙 할 수 있으며, "차를 돌리는"대신 "Car.Turn"이라고 말하는 것은 큰 도약이 아닙니다. 그러나 이러한 객체를 잘 처리하고 만들려면 일반적으로 생각하는 방식을 뒤집어 야합니다.

객체를 조작하는 대신 객체가 실제로 자체적으로 작업하도록 지시합니다. 더 이상 어렵지 않을지 모르지만 창을 열도록 지시하면 이상하게 들립니다. 이런 사고 방식에 익숙하지 않은 사람들은 결국 자연스러워 질 때까지 반복해서 그 이상 함과 싸워야합니다.


7
좋은 통찰력. 문제는 실생활에서 다른 객체와 관련이없는 "객체"가 할 수있는 일이 많지 않다는 것입니다. OO는 객체가 내부 상태를 수정하라는 명령을받는 한 잘 작동합니다 : rectangle.enlarge (margin_in_pixels)하지만 몇 년 전에 한계를 깨달았습니다. 어느 날 우리 프로그래머들은 하드웨어를 설치하고있었습니다. 누군가가 "screw.turn"을 현명하게 깨뜨렸다. 그러나 그것은 생각했다 : 물론, 나사는 방향을 바꿀 수 있지만, 실제로 캐비닛과 나사 사이의 작동이다; 어느 개체도 작업 자체를 수행 할 수 없습니다. OO는 충분하지 않습니다.
DarenW

3
+1, 수년 동안 "substr (date, 0,4)"를 쓴 후 "date.substring (0,4)"를 작성하기가 어렵습니다
ern0

4
코드 스 니펫의 경우 +1 실제 사고 과정을 명확하게 묘사합니다.
Karthik Sreenivasan

2
나는 실제로 당신이 보내는 명령으로 그것을 읽을 것입니다. "차를 좌회전하여 말해"에서와 같이. Oop은 메시지를 객체에 전송하는 것을 기반으로 했으므로 해석하는 방법입니다.
bunglestink

1
좋은 insigh, 그래서 mayby ​​OOP는 "에이전트 시스템"모델링에 더 적합합니까?
Qbik

21

모든 패러다임은 대부분의 사람들이 파악하기 위해 "가장자리를 넘어서"는 특정 추진을 요구합니다. 정의에 따르면, 그것은 새로운 사고 방식이므로, 오래된 개념을 포기하고 새로운 개념이 유용한 이유를 완전히 파악해야합니다.

컴퓨터 프로그래밍을 가르치는 데 사용되는 방법이 일반적으로 매우 열악하다는 것이 많은 문제라고 생각합니다. OOP는 너무 일반적이므로 눈에 띄지 않지만 함수형 프로그래밍에서는 여전히 흔합니다.

  • 중요한 개념은 홀수 이름 뒤에 숨겨져 있습니다 (FP : 모나드 란 무엇입니까? OOP : 왜 그것들을 때때로 함수라고 부르고 다른 방법으로 부르는 이유는 무엇입니까?)

  • 이상한 개념은 실제로하는 일이나 왜 그것을 사용하는지 또는 왜 그것을 사용하려고 생각했는지에 대한 비유로 설명되어 있습니다 (FP : 모나드는 우주복이며 일부 코드를 마무리합니다). 개체는 오리와 같으며 소음을 내고 걸을 수 있으며 동물에서 상속됩니다.)

  • 좋은 물건은 사람마다 다르므로 어떤 학생에게 어떤 전환점이 될지 명확하지 않으며 종종 교사가 기억조차 할 수 없습니다. (FP : 오, 모나드는 매번 일어나는 일을 명시 적으로 기록하지 않고도 유형 자체에서 무언가를 숨기고 계속 수행 할 수있게합니다. OOP : 오, 객체를 사용하면 해당 데이터와 함께 일종의 데이터에 대한 기능을 유지할 수 있습니다.)

가장 나쁜 점은 질문에서 알 수 있듯이 어떤 사람들은 개념이 좋은 이유를 즉시 이해하고 어떤 사람들은 그렇지 않을 것이라는 점을 즉시 이해하게 될 것입니다. 실제로 티핑 포인트가 무엇인지에 달려 있습니다. 나에게있어 객체가 데이터를 저장하고 그 데이터에 대한 방법을 결정하는 것이 핵심이었다. 그런 다음 객체의 메소드 호출이 해당 객체를 첫 번째 매개 변수로 정적 호출하는 것과 매우 유사하다는 것을 깨닫는 것처럼 나중에 뛰어 들었습니다.

나중에 약간의 점프는 이해를 다듬는 데 도움이되지만, "OOP는 말이되지 않습니다. 왜 사람들은 이것을 하는가?" "OOP가 최고입니다. 왜 사람들이 다른 일을합니까?"


8
나는 특히 은유를 싫어하며, 종종 묘사하지 않고 혼란스럽게 만듭니다.
거짓말 라이언

3
"나중에 객체로부터의 메소드 호출이 해당 객체를 첫 번째 매개 변수로 정적 호출하는 것과 매우 유사하다는 것을 깨닫는 것처럼 나중에 뛰어났습니다." 파이썬과 같은 언어로 처음부터 더 강조 되었기를 바랍니다.
Jared Updike 20

1
개념을 설명하기 위해 은유를 사용하는 것에 대한 나의 문제는 교사가 은유 전체를 설명하는 것처럼 종종 은유에서 멈추는 것입니다. 그것은 완전한 설명이 아닙니다. 그것은 실제 설명을 머리를 감싸는 데 도움이되는 그림 일뿐 입니다.
jhocking 2016 년

좋은 답변입니다! OOP를 이해하는 첫 번째 단계는 기초를 잘 이해하고 자연스럽게 확장하는 것보다 더 중요 할 것이라고 설명합니다. : D
Karthik Sreenivasan

"도약"학습에 대한 결론 : OOP를 "단순히"모듈 식 / 구조 / 단계별 구성이지만 스테로이드에 인식하기 시작했을 때; 아주 오래되고 엉망인 유지 보수가 가능한 COBOL 프로그램을 다시 작성할 때. COBOL의 글로벌 범위에도 불구하고 나는 기본적으로 맞춤형 레코드 구조, 단일 목적 변수 및 엄격하게 집중된 모듈 식 및 구조화 된 단락 (방법)으로 OO 원칙을 적용했습니다.
radarbob

15

OOP에 대한 기본 설명은 현장에서 사용되는 방식과 거의 관련이 없습니다. 이를 가르치기위한 대부분의 프로그램은 "차를 물체로 생각하고 바퀴를 물체로, 문과 변속기 ..."와 같은 실제 모델을 사용하려고하지만 모호한 시뮬레이션 프로그래밍의 경우를 제외하고, 객체는 비 물리적 개념을 나타내거나 간접적 인 것을 소개하는 데 훨씬 더 자주 사용됩니다. 그 결과 사람들이 직관적으로 잘못 이해하게됩니다.

설계 패턴에서 가르치는 것은 OOP를 설명하는 훨씬 더 좋은 방법입니다. 프로그래머에게 추상적으로 설명하기보다는 실제 모델링 문제가 어떻게 객체를 효과적으로 공격 할 수 있는지 보여줍니다.


13

나는 dsimcha의 대답에 대부분 동의하지 않습니다.

  1. 처음부터 OO를 가르치는 것은 그 자체로 나쁜 생각이 아니며 절차 언어를 가르치는 것도 아닙니다. 중요한 것은 OO 나 절차에 관계없이 사람들에게 명확하고 간결하며 응집력있는 코드를 작성하도록 가르치는 것입니다.

  2. 좋은 OO 프로그램의 개별적인 방법은 전혀 절차적인 경향이 없습니다. 이것은 OO 언어의 진화 (내가 아는 유일한 다른 OO 언어 인 C ++ 이외의 C ++이기 때문에 C # 읽기)와 하루가 점점 복잡 해지는 구문 (람다, LINQ to 객체 등)으로 점점 더 진실 해지고 있습니다. 절차 적 언어에서 OO 방법과 절차의 유일한 유사점은 각각의 선형 적 특성이며, 곧 변경 될 것으로 의심됩니다.

  3. 데이터 구조를 이해하지 않으면 절차 언어를 마스터 할 수 없습니다. 포인터 개념은 OO 언어와 마찬가지로 절차 언어에 중요합니다. 예를 들어 절차 언어에서 일반적으로 사용되는 매개 변수를 참조로 전달하면 OO 언어를 배우는 데 필요한만큼 포인터를 이해해야합니다.

  4. 디자인 패턴은 OO 프로그래밍의 기본이 아니기 때문에 OO 프로그래밍 초기에 전혀 가르쳐서는 안된다고 생각합니다. 디자인 패턴에 대해 전혀 몰라도 확실히 좋은 OO 프로그래머가 될 수 있습니다. 사실, 사람은 적절한 이름으로 문서화되어 있고 그에 관한 책이 쓰여져 있다는 것을 알지 않고도 잘 알려진 디자인 패턴을 사용할 수 있습니다. 기본적으로 배워야 할 것은 단일 책임, 공개 폐쇄 및 인터페이스 분리와 같은 설계 원칙입니다. 불행히도 요즘 OO 프로그래머라고 생각하는 많은 사람들은이 기본 개념에 익숙하지 않거나 무시하려고 선택하기 때문에 많은 쓰레기 OO 코드가 있습니다.

원래 포스터의 질문에 대답하기 위해 OO는 절차 적 프로그래밍보다 이해하기 어려운 개념입니다. 우리는 실제 객체의 속성과 방법으로 생각하지 않기 때문입니다. 예를 들어, 인간의 두뇌는 "TurnOn"을 TV의 방법으로 쉽게 생각하지 않지만 사람이 TV를 켜는 기능으로 간주합니다. 유사하게, 다형성은 일반적으로 하나의 "얼굴"에 의해 각각의 실제 객체를 보는 인간 두뇌에 대한 외래 개념이다. 상속은 다시 우리의 뇌에 자연스럽지 않습니다. 내가 개발자라고해서 내 아들이 하나라는 뜻은 아닙니다. 일반적으로, 인간의 두뇌는 OO를 배우도록 훈련을 받아야하지만 절차 적 언어는 더 자연 스럽습니다.


2
+1-나도 기본적인 수준에서 OOP 교육에 디자인 패턴이 필요하다고 생각하지 않습니다. 훌륭한 OOP 프로그래머가 될 수 있으며 디자인 패턴을 모를 수 있습니다. 반대로, 알려진 OOP 프로그래머로부터 알려진 디자인 패턴이 자연스럽게 나타나는 경향이 있습니다. 디자인 패턴은 항상 발명 된 것이 아니라 발견됩니다.
Gary Willoughby

1
+1-좋은 답변입니다. 네가 말한 네 번째 요점을 좋아한다. 디자인 패턴이 실제로 무엇인지 모른 채 좋은 OO 프로그래머가 될 수 있다는 것은 매우 사실입니다 !
Karthik Sreenivasan

나는 대부분의 디자인 패턴이 언어의 한계 주위를 표현 적으로 표현하기위한 풍선 껌 / 덕트 테이프 방식 일 뿐이므로 # 4에 동의합니다. 다른 패러다임에서는 디자인 패턴이 완전히 다를 수 있으며 자체 제약 조건에 따라 달라질 수 있습니다. 나는 2에 ​​동의하지 않는다. LINQ와 람다는 여전히 깔끔하게 패키지 된 상위 레벨 추상화를 제공하는 절차 적 방식으로 실행된다. JavaScript와 같이 동적으로 형식화 된 절차 / 기능 언어를 사용하여 개발하는 데 상당한 시간을 투자하면 무슨 뜻인지 알 수 있습니다.
Evan Plaice

6

저는 많은 프로그래머들이 초기 설계 및 시작 계획에 어려움을 겪고 있다고 생각합니다. 누군가가 당신을 위해 모든 디자인을 수행하더라도 OOP 원칙에서 벗어날 수 있습니다. 많은 스파게티 코드를 가져 와서 클래스에 덤프하면 실제로 OOP입니까? OOP를 이해하지 못하는 사람은 여전히 ​​Java로 프로그래밍 할 수 있습니다. 또한 특정 방법론을 따르지 않거나 동의하지 않는 것에 대해 이해하기 어려워하지 마십시오.


5

절대 객체 를 읽어야 합니까? 글쎄, 거의. Mordechai Ben-Ari (ACM 멤버쉽 필요)는 OOP가 너무 어렵다고 제안합니다. 이는 실제로 모델링에있어 자연스러운 패러다임이 아니기 때문입니다. (나는 기사에 대해 예약을 했음에도 불구하고 프로그램이 OO 언어를 사용하는 절차 적 패러다임과 반대로 OOP 패러다임에 작성되었다고 말하기 위해 프로그램이 어떤 기준을 충족시켜야한다고 생각하는지 명확하지 않기 때문에.


5

객체 지향 프로그래밍 자체는 어렵지 않습니다.

어려운 부분은 잘하고 있습니다. 코드 사이에 잘라내기를 배치하여 공통 기본 개체로 쉽게 이동하고 나중에 확장 할 수있는 위치는 어디입니까? 농구대를 뛰어 넘지 않고 다른 사람 (확장 클래스, 프록시 랩, 메서드 재정의)에서 코드를 사용 가능하게 만드는 방법.

그것은 어려운 부분이며, 올바르게 행하면 매우 우아 할 수 있으며, 심하게 행하면 매우 어설프게 될 수 있습니다 . 내 개인적인 경험은 많은 연습이 충분히 잘을 수행하려면, 당신은 당신이 다른 생각을했다 소원하는 모든 상황에 있었던 데 필요한 것입니다 시간을.


"제 개인적인 경험은 이번에 충분히 잘하기 위해서 당신이 다르게 행동하길 바라는 모든 상황에서 많은 연습이 필요하다는 것입니다." OOP는 잘못하지 않은 방법으로 체계화 된 목록처럼 보이며, 모든 방법을 잘못 수행하기 전까지는 의미가 없습니다.
Jared Updike

@Jared,별로. 그것을 sodukus 해결과 비교하십시오. 그것을 해결하기 위해 할 수있는 다양한 트릭이 있지만 역 추적없이 잘 수행하려면 시간과 연습이 필요합니다.

"공통 기본 객체"를 공통 조상으로 생각하면 명확 해집니다. 정말 간단합니다. 똑똑해 보이려는 사람들로부터 오해의 소지가 많은 설명이 있기 때문에 이해하기 어렵습니다.
annoying_squid

4

방금 Richard Feynman의 비디오를보고 사람들이 생각할 때 실제로 완전히 다른 방법론이 어떻게 진행되고 있는지 이야기했습니다.

높은 수준의 디자인을 할 때 객체를 시각화하고 객체를보고 인터페이스를보고 정보가 통과해야하는 경로를 확인할 수 있습니다.

또한 세부 사항을 기억하는 데 어려움을 겪고 OO가 조직적인 도움이된다는 것을 알았습니다. 느슨하게 구성된 서브 루틴 목록을 스캔하는 것보다 기능을 찾기가 훨씬 쉽습니다.

나에게 OO는 큰 이점 이었지만, 같은 방식으로 시각화하지 않거나 높은 수준의 아키텍처를 수행하지 않으면 아마도 무의미하고 성가신 것입니다.


+1 같은 느낌이지만 루비 믹스 인을 포함하여 반대 방향으로 많은 푸시가 있습니다. 이렇게하면 엄격한 OO가 모두에게 해당되는 것은 아니라는 것을 알게됩니다.
Dan Rosenstark

@Yar Yep, 그것은 내가 말한 것과 거의 같습니다. 개인적으로 더 나은 것을 상상할 수는 없지만 (루비가 내가 사용한 해 동안 NUTS를 몰아 냈습니다), 나는 모든 사람들이 그것을 보는 다른 방법을 가지고 있음을 인정하기 시작했습니다. 어쩌면 어떤 사람들은 생각하는 대신 시각화 나 터치를 듣거나 OO를 사용하지 않을 수도 있습니다.
Bill K

더 자연스러운 명명 규칙을 장려하는 데 도움이된다고 생각합니다. 더 이상 (같은 함수 이름으로 함수의 유형을 인코딩 할 필요가 없습니다 INSTR) - 이름이 유형에 부착되어 있기 때문에 (같은 string::find)
켄 블룸

@Ken 동의하지만 OO보다 강력한 타이핑의 문제라고 생각합니다. 루비에는 OO가 있지만 오리 타이핑으로 인해 많은 유형 정보가 손실됩니다. 루비는 단지 "보내기 (it)"라고 말하고 기대합니다. 작동하기 위해 어떤 "매직"메소드를 구현해야하는지 알아야합니다.
Bill K

@ 빌, 당신 말이 맞아요. 일반적인 프로그래밍을 지원하는 언어의 문제입니다. Haskell과 같은 모듈 및 타입 클래스 시스템으로 멋진 자연 명명 규칙을 얻을 수 있으며 Haskell에 대한 OO는 없습니다. C에 과부하가 걸린 경우 C에서도 같은 종류의 일반 이름을 얻을 수 있습니다.
Ken Bloom

4

나는 OO를 소개하기 전에 GW-Basic과 Turbo Pascal 프로그래밍을 꽤 조금 했으므로 처음에는 머리를 숙였다 .

이것이 다른 사람들에게 어떤 일이 일어나는지 모르겠지만, 나에게는 다음과 같습니다. 프로그래밍에 대한 나의 사고 과정은 순전히 절차 적이었습니다. 에서와 같이 : "그런 일이 발생하면 다음에 그런 일이 일어납니다"등. 나는 변수와 데이터가 프로그램의 흐름에서 도망 치는 행위자 이상으로 간주하지 않았습니다. 프로그래밍은 "행동의 흐름"이었습니다.

나는 이해하기 쉽지 않은 것이 (지금 바보처럼) 어리석은 것처럼 데이터 / 변수가 실제로 정말로 중요 하다는 생각이라고 생각합니다 . 또는이 다른 방법을 넣어 : 내가 무엇을 통해 그것을 이해하려고 노력 계속 일이 아니라 무엇을 통해보다 을 파악하는 실제 키이다.


흥미로운 관점. 방대한 C ++ 프로젝트를 이해하려고 노력할 때, 나는 주로 데이터의 관점에서 일부 "입력"에서 "출력"까지 비트의 "신호 경로"를 생각하면서 반대라고 생각합니다. 저도 베이직과 파스칼을 많이했지만, 가장 초기의 기술적 사고는 전자 공학이었습니다.
DarenW

3

이해하기 어렵다고 생각하지는 않지만 많은 프로그래머가 절차 언어에서 나온 개념에 익숙하지 않을 수 있습니다.

내가 (많은 포럼에서) 많은 사람들을 보거나 읽은 것으로부터 OOP의 '결과'를 찾습니다. 돌아가서 수정하지 않는 절차 적 프로그래머라면 코드를 확장하는 것이 이점을 이해하기 어려울 수 있습니다.

또한, 사람들이 그것을 읽고 /보고 있다면, 그들이 왜 어려운지 알기 쉽다는 나쁜 OOP가 많이 있습니다.

IMO 당신은 그것이 '클릭'될 때까지 기다려야하거나 실제 지식을 가진 사람에 의해 가르쳐 질 필요가 있습니다. 나는 당신이 서두를 수 있다고 생각하지 않습니다.


5
학업 환경에서 온 경우, OOP에서 작성하는 장난감 프로그램의 유형이 실제로 무의미 해 보입니다. 나는 대학에서 C를 배우기 시작했고, 모든 프로그램이 100 페이지 미만인 1 페이지이기 때문에 이해하기가 쉬웠다. 그런 다음 OOP를 배우려고하면 동일한 짐을지기 위해 물체의 모든 수하물과 오버 헤드가 필요하며 무의미합니다. 그러나 많은 파일과 수천 줄에 걸쳐 프로그램을 작성하기 전까지는 어떤 프로그래밍 스타일이 유용한 지 알기가 어렵습니다.
CodexArcanum

3

OOP가 어려운 이유는 도구가 실제로이를 용이하게하지 않기 때문입니다.

오늘날 컴퓨터 언어는 컴퓨터에서 일어나는 일을 추상화 한 것입니다.

OOP는 추상화를 나타내는 추상적 인 방법입니다.

따라서 추상화를 사용하여 추상화로 추상화를 작성합니다. 여기에 우리가 추상화하는 것은 일반적으로 매우 복잡한 신체적 / 사회적 상호 작용이며, 당연한 일입니다.


2

실제로 "객체 지향 프로그래밍의 투쟁"이라는 블로그가 있는데, 그 내용을 배우는 데 어려움을 겪고 있습니다. 절차 적 프로그래밍을 사용하는 데 많은 시간을 소비했기 때문에 이해하기가 특히 어려웠으며 객체가 속성 및 동작 모음으로 표현 될 수 있다는 아이디어를 이해하는 데 어려움을 겪었습니다. 단순히 변수와 메소드의 집합).

또한 상속, 인터페이스, 다형성, 구성 등과 같은 언어 객체 지향 개념을 만드는 많은 개념이 있습니다. 실제로 코드를 효과적으로 작성하고 객체 지향으로 작성하기 전에 이론에 대해 많은 것을 배울 수 있습니다. 절차 적 프로그래밍에서는 변수에 대한 메모리 할당 및 다른 메소드에 대한 진입 점 호출과 같은 것을 이해하는 것만으로도 문제가되지 않습니다.


동의-사람들이 OO와 함께하는 많은 어려움은 그들이 '절차 적으로'생각하도록 훈련했다는 것입니다. OO에 대해 본질적으로 어려운 것은 없지만 절차 기술을 '알고'있다면 다른 방식으로 구조를 구성하는 것이 매우 놀라운 일입니다.
Kirk Broadhurst

의심 할 여지없이 그것은 절차 적 프로그래밍과 전혀 다른 사고 방식입니다. 그러나 많은 사람들이 말하는 것과는 달리 A) 부 자연스러운 사고 방식과 B) 복잡한 것은 아닙니다. 나는 그것이 잘 가르쳐지지 않았다고 생각합니다.
annoying_squid

2

동기. 왜 그런지 알지 못했을 때, 그리고 내가 한 일을보고 제대로하지 않았는지 알아낼 수 없을 때 무언가를 배우기가 더 어렵습니다.

OO를 사용하여 유용한 작업을 수행하는 소규모 프로젝트가 필요합니다. 디자인 패턴에 대한 책을 살펴보고 분명히 유용하고 OO와 잘 어울리는 책을 제안하는 것이 좋습니다. (전 시도했을 때 전략을 사용했습니다. Flyweight 또는 Singleton과 같은 것은 일반적으로 객체를 사용하고 객체를 사용하여 무언가를 달성하는 방법이 아니므로 잘못된 선택입니다.)


사람들은 항상 싱글 톤에 대해 이야기하지 않지만 항상 파티에 초대됩니다. 그러나 그는 비 OO OO DP입니다.
Dan Rosenstark

-1

나이 (경험의 대변인)와 더 중요한 관심사에 달려 있다고 생각합니다. 당신이 "젊은"(즉, 아마도 녹색)이고 다른 방법을 생각한 적이 없다면, 그것은 매우 간단 해 보입니다. 반면에, 그것이 당신이 본 것 중 가장 멋진 일이라고 생각한다면 – 28 세 때 나에게 일어난 일입니다.

반면에, 많은 자바 학생들이했던 것처럼 "우리가 왜 이것을 배우는가는 유행 일뿐"이라고 생각한다면 실제로 배우는 것은 불가능합니다. 대부분의 기술에서 마찬가지입니다.


1
OO 유행? 몇 살은 학생이다 -이 "유행"는 그들보다 나이가 의심 (- 내가했던 알고 있었다 - 내가 한 첫 OO에 대한 4분의 1,983에서 시뮬이고 시뮬 그 시점에서 새로운 아니었다)
머피

@Murph 2004-2005 년경에 학생들은 45-50 세 (이베리아의 전문 프로그래머) 이상이었습니다.
Dan Rosenstark

좋아, 나는 그들이 어떻게 OO 일의 시작을 놓쳤는 지 알 수 있습니다. 이 하나의 유행으로 설명 할 수 개발에 일을하지만 빨리 흐지부지하지 않는 사람들은 좋은 물건으로 진화하는 경향이있다 - 그러나 2004/5에 의해 우리는 OO를 (벽하는 거의 벽 인 .NET으로 잘했다
머피

1
@Murph는 솔직히이 사람들이 자바로 전환하려고하는 메인 프레임 프로그래머였습니다. 실제로는 재미 있고 독특한 경험이었습니다 (Java Trainer 시절에는 정상 요금이 아님). 그것은 이다 그들은 많은 일들이 왕래하지만, 분명히 OO가 유행보다 더 보았다고하지만, 사실. 별도의 참고 사항 : 나는이 단위 테스트가 유행으로
사라질

-1

어떤 패러다임 (OOP, 기능 등)을 선택하든 컴퓨터 프로그램을 작성하려면 프로그램이 어떤 단계를 수행해야하는지 알아야합니다.

프로세스를 정의하는 자연스러운 방법은 단계를 작성하는 것입니다. 큰 작업의 경우 작업을 작은 단계로 나눕니다. 이것은 절차적인 방법이며, 컴퓨터의 작동 방식이며, 점검 목록을 단계별로 수행하는 방법입니다.

OOP는 다른 사고 방식입니다. 단계별로 수행해야 할 작업 체크리스트를 생각하는 대신 대상, 능력 및 관계를 생각해야합니다. 따라서 많은 객체, 작은 메소드를 작성하고 프로그램이 마술처럼 작동합니다. 이를 달성하려면 마음을 비틀어 야합니다 ...

이것이 OOP가 어려운 이유입니다. 모든 것이 하나의 대상이기 때문에, 그들이하는 것은 다른 대상에게 무언가를하도록 요구하는 것 뿐이며, 다른 대상은 기본적으로 어떤 것을합니다. 따라서 OOP 프로그램의 제어는 개체간에 크게 앞뒤로 이동할 수 있습니다.


-1

현재 프로그래밍을 배우고이 분야에서 문제가있는 사람으로서, 나는이 개념의 구체적인 구현과 같이 개념을 이해하기가 너무 어렵다고 생각하지 않습니다. 나는 OOP에 대한 아이디어를 얻었 기 때문에 이것을 말하고 PHP에서 약 1 년 동안 사용했지만 C #으로 이동하여 다른 프로그래머의 객체 사용을 살펴보면 많은 사람들이 그렇게하는 것을 알게됩니다. 나는 단지 이해하지 못한다. 이것이 OOP의 원리를 더 잘 이해하게하는 길로 이끌었습니다.

물론, 문제는 아마도 기본적으로 OOO 언어에 대한 경험이 부족할 가능성이 높으며 시간이 지남에 따라 새로운 프로그래머에게 분명하지 않은 객체를 활용하는 새로운 방법을 찾을 것입니다. 현재 경험하고 있습니다. Jerry Coffin은 특히 그의 의견에서 몇 번 언급했습니다.

이는 OOP의 큰 장점이 현실을 더욱 밀접하게 모델링한다고 들었을 때 특히 문제가됩니다. 현실.

누군가가 실제로 사물이 아닌 것들에 대한 클래스를 만들 때 종종 볼 수있는 인상이기 때문에 이것이 매우 정확하다는 것을 알았습니다. 특정 예제는 나를 피할 수는 있지만 가장 가까운 거리는 거리를 다루는 것입니다. 객체 (다음에이 같은 혼란을 일으키는 것을 볼 때 편집 할 것입니다). 때때로 OOP는 자체 규칙을 일시적으로 무시하고 덜 직관적 인 것처럼 보입니다. 이것은 객체가 객체를 생성 할 때 발생하는 경우가 많으며,이를 캡슐화하는 클래스에서 상속하는 경우가 많습니다.

나는 나와 같은 누군가를 위해 객체의 개념을 여러 측면을 갖는 것으로 생각하는 데 도움이되며, 그중 하나는 그렇지 않은 경우 객체와 같은 것을 처리하는 것을 포함합니다. 약간의 패러다임 전환으로 거리와 같은 것이 이론적 인 대상으로 나올 수는 있지만 손에 넣을 수는 없습니다. 나는 속성 집합을 가지고 있지만 속성에 액세스하는 것과 같은보다 추상적 인 행동 집합을 가지고 있다고 생각해야합니다. 나는 이것이 내 이해의 열쇠라고 긍정적이지는 않지만, 현재의 연구가 이끄는 곳인 것 같습니다.


1
한 쌍의 점 또는 객체는 객체로 간주되어야합니다. 거리는 물체에서 함수로 가져와야합니다. 객체를 사용한다고해서 모든 것에서 객체를 만드는 것은 아닙니다.
Gangnus

내가 말했듯이, 거리는 좋지 않은 예입니다. 모든 것에서 물건을 만드는 것에 관해서는, 실제로 내가 한 일이 아니라 내가 본 것을 구체적으로 언급하고 있습니다. 아직 아무것도 아닙니다.
dsimer

언어에 따라 다릅니다. 스몰 토크에서 거리 (및 모든 것)는 객체입니다. 그러나 C #에서는 좋지 않을 것이라고 언급했습니다.
Gangnus

-2

객체 지향 프로그래밍 (POOP)의 원리를 배울 때 용어는 길에서 내 충돌이었다. 조각이 제자리에 들어가기 시작하는 기초를 파악할 때입니다. 새로운 개념을 배우는 모든 것이 조금 어려울 것입니다.

디자인 패턴은 최소한 OOP와 평행을 이루어야한다는 데 동의했습니다.


-2

나를위한 주요한 점프는 OOP의 추상 개념을 이해하는 것이 었습니다. 이제는 프로그래밍에 익숙하지 않다 .1 년에서 1 년 반 동안 프로그래밍을 해왔으므로 OOP에 대한 소개는 Actionscript and Processing을 사용했다. 내가 Actionscript 코딩을 처음 배웠을 때 OOP에 없었습니다. 액션 패널에 직접 코딩하는 법을 배웠으며 프로그래밍의 기본 원리 (변수, 함수, 루프 등)를 배웠습니다. 그래서 Flash 또는 Processing에서 스테이지에 직접 무언가를하는 것으로 배웠습니다.

OOP가 등장했을 때, 객체 내에서 사용하고 재사용 할 수있는 메서드와 속성을 만들 수 있다는 것을 깨닫는 것은 처음에는 조금 어려웠습니다. 모든 것이 매우 추상적이고 처리하기 어려웠지만 프로그래밍 언어 자체는 훨씬 나아졌지 만 처음에는 그러한 연결을 만들기 위해 믿음의 도약이 필요했습니다.


와우의 일부를 이해하지 못했습니다. "모든 것은 내가 OOP있어 일단 이해하는 것이 훨씬 더 쉽게되었다 클래스 등 객체의 인스턴스하지만 프로그래밍 언어를 처리하는 데 매우 추상적이고 어렵다고하지만 좀 처음에는 이러한 연결을 만들기 위해 faitl의 도약을했다."

-2

레시피

좋은 OOP 이해 = 좋은 멘토 또는 좋은 책 또는 둘 다 + 개인적 관심 + 실습.

개인적인 관심

개인적인 경험에서 개인적인 관심은 절차 적 프로그래밍에서 OOP 로의 다리를 건너는 멘토 나 좋은 책 또는 둘 다의 올바른 입력으로 먼 길을 왔습니다 .

연습, 연습 및 연습

OOP를 더 잘 이해하는 가장 친한 친구연습 에 지나지 않았습니다 . 이것은 분명히 OOP 능력을 키울 것입니다.

속담으로 "열심히 일을 대신하고 성공에 지름길은 없다."

행운을 빕니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.