OOP vs 기능 프로그래밍 vs 절차 적 [닫힘]


237

이러한 프로그래밍 패러다임의 차이점은 무엇이며 특정 문제에 더 적합합니까?

건축 사례에 감사드립니다!


이것은 완전한 대답은 아니지만, "기능적"이 "OO"스타일 (F #의 맥락에서)에 어떻게 영향을 미치는지, lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511에 대해 약간 씁니다. 입장
브라이언

이것을 읽는 것을 고려할 수도 있습니다 ! 주요 차이점, 장단점 등이 어떤 개미를 언제 사용해야하는지에 대한 많은 예가 있습니다
Nikita Ignatov



Bob 아저씨는 이것에 대해 트윗 했습니다. 또한 여기에 .
jaco0646

답변:


129

그들 모두는 그들 자신의 방식으로 훌륭합니다-그들은 같은 문제에 대한 단순히 다른 접근법입니다.

순전히 절차적인 스타일에서 데이터는 데이터에서 작동하는 기능과 크게 분리되는 경향이 있습니다.

객체 지향 스타일에서 데이터는 함수 모음을 가지고 있습니다.

기능적 스타일에서, 데이터와 함수는 (Lisp 및 Scheme에서와 같이) 서로 공통적 인 경향이있는 반면 함수가 실제로 어떻게 사용되는지에 대한 유연성을 제공합니다. 알고리즘은 루프와 반복보다는 재귀와 구성 측면에서 정의되는 경향이 있습니다.

물론 언어 자체는 어떤 스타일이 선호되는지에만 영향을줍니다. Haskell과 같은 순수 기능 언어에서도 절차 스타일 (권장하지는 않지만)을 작성할 수 있으며 C와 같은 절차 언어에서도 객체 지향 스타일 (예 : GTK + 및 EFL API).

분명히, 각 패러다임의 "이점"은 단순히 알고리즘과 데이터 구조의 모델링에 있습니다. 예를 들어 알고리즘에 목록과 트리가 포함 된 경우 기능 알고리즘이 가장 합리적 일 수 있습니다. 예를 들어 데이터가 고도로 구조화 된 경우 언어의 기본 패러다임 인 경우 객체로 작성하는 것이 더 합리적 일 수 있습니다. 또는 모나드의 기능적 추상화처럼 쉽게 작성할 수 있습니다. Haskell 또는 ML과 같은 언어의 기본 패러다임입니다.

사용하는 선택은 단순히 프로젝트와 언어가 지원하는 추상화에 더 적합한 것입니다.


5
당신이 말한 것은 당신이 쓴 것을 반영하지 않는 것 같습니다. 당신은 그들이 "장단점"을 가지고 있지 않다고 말한 다음 어떻게 다른 접근 방식인지 말합니다. 주어진 상황에 따라 누군가가 다른 방법보다 하나의 접근법을 선택하는 이유는 무엇입니까? 강점과 약점, 장단점. 나는 하나가 본질적으로 더 좋다고 말하지 않으며, 당신도 마찬가지였습니다. 나는 그것이 당신이 정말로 말하려는 것이라고 생각합니다. 선택한 접근 방식에 다른 접근 방식에 비해 긍정적 및 부정적 요소가 없다고 생각하지 않는 한.
JM Becker

1
@ TechZilla : 내 말이 잘못되었다는 데 동의하지만, 의미하는 것은 언어 X가 알고리즘 U와 언어를 작성하는 데 더 적합하다는 것을 인정하지 않고 언어 X가 Y보다 낫다고 말할 수있는 기능 목록이 실제로 없다는 것입니다. Y는 알고리즘 V를 작성하는 데 더 적합 할 수 있지만 둘 다 어느 언어로든 쉽게 구현할 수 있습니다.
greyfade

2
절차 적 기능과 기능적 차이점은 명확하지 않습니다. 나는 College에서 Scheme / Rackett을 배우고 있지만 실제로는 C와 PHP의 큰 차이점을 볼 수 없습니다. 예를 들어 주시겠습니까?
Leonel

7
@Leonel : 대부분의 사람들이 인용하는 가장 큰 차이점은 절차 적 언어에서는 for 루프를 사용할 수 있지만 기능적 언어는 그렇지 않다는 것입니다. 대신 함수에 대한 재귀 호출을 사용하여 동일한 작업을 수행합니다. 함수형 언어는 함수를 일류 객체로 만듭니다-숫자처럼 전달할 수는 있지만 C에서는 그렇게 할 수 없습니다 (그리고 PHP의 지원은 중단되었습니다).
greyfade

2
@tastro : 한 패러다임이 다른 패러다임보다 더 의미가있을 때. 그게 다야. 때로는 함수의 구성으로 코드를 모델링하는 것이 더 합리적이고 때로는 데이터를 객체로 모델링하는 것이 더 합리적입니다. 알고리즘과 데이터 구조를 표현하는 방법에는 여러 가지가 있습니다. OOP와 기능은 그 중 두 가지입니다.
greyfade

25

사용 가능한 라이브러리, 도구, 예제 및 커뮤니티가 오늘날 패러다임을 완전히 능가한다고 생각합니다. 예를 들어 ML (또는 기타)은 궁극적 인 다용도 프로그래밍 언어 일 수 있습니다. 일 수 있지만 수행중인 작업에 적합한 라이브러리를 얻을 수 없으면 문제가 있습니다.

예를 들어, 비디오 게임을 만드는 경우 C ++에는 더 좋은 코드 예제와 SDK가 있으므로 아마도 더 좋은 방법 일 것입니다. 소규모 웹 응용 프로그램의 경우 매우 빠른 Python, PHP 및 Ruby 프레임 워크가있어 매우 빠르게 실행할 수 있습니다. 컴파일 타임 확인 및 엔터프라이즈 라이브러리 및 플랫폼으로 인해 Java는 대규모 프로젝트에 적합합니다.

예전에는 다른 언어의 표준 라이브러리가 C, C ++, 어셈블러, ML, LISP 등과 같이 매우 작고 쉽게 복제 된 경우가있었습니다. 네트워크 통신, 암호화, 그래픽, 데이터 파일 형식 (XML 포함), 심지어 균형 잡힌 트리 및 해시 테이블과 같은 기본 데이터 구조도 제외되었습니다!

Python, PHP, Ruby 및 Java와 같은 현대 언어에는 이제 훨씬 더 표준 라이브러리가 제공되며 라이브러리가 서로 충돌하지 않도록 네임 스페이스를 채택하여 쉽게 사용할 수있는 많은 타사 라이브러리가 있습니다. 라이브러리의 메모리 관리 체계를 표준화하기위한 가비지 콜렉션.


5
Python, ruby는 C 또는 LISP와 같은 "표준"라이브러리가 없습니다. 단일 구현 언어이기 때문입니다. 귀도의 말에 따르면 파이썬은 표준이 없습니다. 요즘 특정 C 또는 LISP (또는 무엇이든) 구현에는 표준 라이브러리 이외의 많은 라이브러리가 제공됩니다.
댄 안드레아 타

8
문제는 객체 지향, 기능 및 절차 적 프로그래밍의 차이점에 관한 것입니다. 이 답변에 언급 된 언어는 확실히 이러한 접근 방식 중 하나에 적합하지만, "사용 가능한 라이브러리 [...] [트럼프] 패러다임"인지 여부에 관계없이 답변은 이러한 개념을 언급하지 않습니다. 그 질문에 대한 답을 얻지 못하므로 완전히 유효한 질문을 회피합니다.
rinogo


20

이 패러다임은 상호 배타적 일 필요는 없습니다. 파이썬을 보면 함수와 클래스를 지원하지만 동시에 함수를 포함한 모든 것이 객체입니다. 기능 / oop / procedural 스타일을 모두 하나의 코드로 혼합하고 일치시킬 수 있습니다.

내가 의미하는 것은 기능적 언어 (적어도 내가 연구 한 유일한 하스켈에서는)에는 진술이 없다는 것입니다! 함수는 그 안에 하나의 표현 만 허용됩니다 !! 그러나 기능은 일류 시민이며 다른 기능과 함께 매개 변수로 전달할 수 있습니다. 몇 줄의 코드만으로도 강력한 작업을 수행 할 수 있습니다.

C와 같은 절차 적 언어로 함수를 전달할 수있는 유일한 방법은 함수 포인터를 사용하는 것 뿐이며 그 자체만으로는 많은 강력한 작업을 수행 할 수 없습니다.

파이썬에서 함수는 일류 시민이지만 임의의 수의 명령문을 포함 할 수 있습니다. 따라서 절차 코드가 포함 된 함수를 사용할 수 있지만 함수형 언어와 같이 함수를 전달할 수 있습니다.

OOP도 마찬가지입니다. Java와 같은 언어에서는 클래스 외부에서 프로 시저 / 함수를 작성할 수 없습니다. 함수를 전달하는 유일한 방법은 해당 함수를 구현하는 객체로 감싸고 해당 객체를 전달하는 것입니다.

파이썬에서는이 제한이 없습니다.


나는 당신이이 패러다임이 상호 배타적 일 필요는 없다는 것을 의미한다고 생각합니다. 그 중 3 입니다 (언어가 허용하는 경우) 그 이상적으로는 하나의 프로그램에서 그들의 3 일, 2를 사용하거나 수에 직교.
Joe Pineda

예, 저는 상호 배타적 인 것이 더 나은 용어라고 생각합니다! 감사
하센

14

GUI의 경우 객체 지향 패러 다마가 매우 적합하다고 말하고 싶습니다. 창은 개체이고 텍스트 상자는 개체이며 확인 단추도 하나입니다. 반면 문자열 처리와 같은 작업은 오버 헤드가 훨씬 적으므로 간단한 절차 적 패러다임을 통해보다 간단합니다.

나는 그것이 언어의 문제라고 생각하지 않습니다. 거의 모든 대중적인 언어로 기능적, 절차 적 또는 객체 지향적을 작성할 수 있지만 일부는 추가 노력이 필요할 수 있습니다.


17
"Object = GUI widget"이라는 오해를 영속시키기 위해 공감하고 싶은 마음이 들지만, 삼가겠습니다. OOP는 "Window"및 "Button"과 같은 가시적 인 인터페이스 요소와 같이 "UserAccount"또는 "PendingSale"과 같은 추상 개념을 나타내는 데에도 효과적입니다.
Dave Sherohman

5
나는 창문이 객체가 될 수 있다고 썼다. 모든 객체가 거기에서 창이라는 결론을 어떻게 내립니까? 단지 예일뿐입니다. 물론 OOP를 사용하여 추상 엔터티와 해당 관계를 모델링 할 수도 있습니다. 어쨌든, downvoting하지 주셔서 감사합니다. 어쨌든 많은 포인트가 없습니다 : D
panschk

6
-1. OOP는 GUI와 관련이 없습니다. GUI를 디자인하는 가장 좋은 방법은 외부 텍스트 파일 (예 : HTML)을 사용하는 것이 이상적입니다. 문자열 처리와 같은 것은 실제로 객체로 훨씬 더 잘 수행됩니다. (C의 문자열에 대해 생각하십시오) !!
hasen

1
잘 모르겠습니다. 어쩌면 객체로 프로그래밍하는 데 익숙 할 수도 있습니다. 그러나 TextBox Y의 값이 객체를 사용하지 않고 변경되었을 때 TextBox X의 값을 변경하는 것과 같은 대화식 작업을 어떻게 수행합니까? 좋아, 당신은 단순히 모든 것에 대해 글로벌 변수를 사용할 수 있습니다 ...
panschk

1
문자열 처리는 perl에서 훌륭하게 수행되지만 (Java, C ++ 또는 C #보다 100 배 우수) 언어의 문자열 기능은 절대 객체 지향이 아닙니다. C의 문자열 처리는 끔찍했지만 C가 유일한 절차 적 언어는 아닙니다 (최고도 아닙니다).
Joe Pineda

6

귀하의 질문에 대답하려면 두 가지 요소가 필요합니다.

  1. 다양한 아키텍처 스타일 / 패턴의 특성 이해
  2. 다른 프로그래밍 패러다임의 특성 이해

소프트웨어 아키텍처 스타일 / 패턴 목록은 소프트웨어 아키텍처 기사에 나와 있습니다. Wikipeida 에 나와 있습니다. 또한 웹에서 쉽게 조사 할 수 있습니다.

간단히 말해서 절차는 절차를 따르는 모델에 적합하고, OOP는 설계에 적합하며, 기능은 고급 프로그래밍에 적합합니다.

각 패러다임의 역사를 읽고 사람들이 왜 그것을 만들고 왜 쉽게 이해할 수 있는지 알아봐야한다고 생각합니다.

둘 다 이해 한 후에는 아키텍처 스타일 / 패턴 항목을 프로그래밍 패러다임에 연결할 수 있습니다.


2

나는 그것들이 종종 "대"하지 않다고 생각하지만, 그것들을 결합 할 수 있습니다. 또한 종종 언급하는 단어는 유행어라고 생각합니다. 그들이 가장 사악한 복음 전파 자라도 "객체 지향"이 무엇을 의미하는지 실제로 아는 사람은 거의 없습니다.


1

내 친구 중 하나가 NVIDIA CUDA를 사용하여 그래픽 앱을 작성하고 있습니다. 응용 프로그램은 OOP 패러다임에 매우 적합하며 문제는 모듈로 깔끔하게 분해 될 수 있습니다. 그러나 CUDA를 사용하려면 상속을 지원하지 않는 C를 사용해야합니다. 합니다. 따라서 영리해야합니다.

a) 당신은 어느 정도 상속을 모방 할 영리한 시스템을 고안합니다. 할 수 있습니다!

i) 후크 시스템을 사용할 수 있습니다 부모 P의 모든 하위 C가 함수 F에 대해 특정 대체를 갖도록 기대할 수 있습니다. 필요한 경우 저장 및 호출되는 하위를 대체로 등록 할 수 있습니다.

ii) 구조체 메모리 정렬을 사용할 수 있습니다 기능을 사용하여 어린이를 부모에게 캐스트 .

이것은 깔끔 할 수 있지만 미래를 보장하는 안정적인 솔루션을 찾는 것은 쉽지 않습니다. 시스템을 설계하는 데 많은 시간을 소비하며 프로젝트 도중에 문제가 발생하지 않을 것이라는 보장은 없습니다. 다중 상속을 구현 하는 것은 거의 불가능하지는 않지만 훨씬 어렵습니다.

b) 일관된 이름 지정 정책을 사용하고 분할 및 정복 방식을 사용하여 프로그램을 작성할 수 있습니다. 상속은 없지만 함수가 작고 이해하기 쉽고 일관된 형식이기 때문에 필요하지 않습니다. 작성해야하는 코드의 양이 증가함에 따라 집중하기가 매우 어렵고 쉬운 솔루션 (해킹)에 굴복하지 않습니다. 그러나이 닌자 코딩 방식은 C 코딩 방식입니다. 낮은 수준의 자유와 좋은 코드 작성 사이의 균형을 유지하십시오. 이를 달성하는 좋은 방법은 기능적 언어를 사용하여 프로토 타입을 작성하는 것입니다. 예를 들어, Haskell 은 프로토 타이핑 알고리즘에 매우 적합합니다.

나는 접근하는 경향이있다 b. 나는 접근법 a를 사용하여 가능한 해결책을 작성했으며 솔직히 말하면 그 코드를 사용하는 것은 매우 부자연 스럽습니다.


첫 번째 C ++ 코 필러는 C 코드를 생성 한 전처리기에 불과했습니다. 따라서 다중 상속을 포함한 c ++의 모든 기능은 C를 사용하여 구현할 수 있습니다 (C에서 c ++ 예외 처리를 에뮬레이션하려면 예외에 대한 일종의 플랫폼 지원이 필요하지만 c ++ 구현에도 필요하므로 기본이 아니라고 생각합니다. 아이디어가 잘못되었습니다).
Chris Becke

2
@Chris Becke 당신의 대답은 너무 철학적입니다. 하나, C는 여러 표준 (수년 동안)을 가지고 있으며, C ++은 물론 C 컴파일러가 완전히 채택한 표준은 거의 없습니다. C ++은 C 구문을 사용하기 때문에 C의 수퍼 세트라고 말하면 큰 노력없이 다른 C 컴파일러에서 컴파일하는 하나의 C 컴파일러에 대한 코드를 작성할 수도 없기 때문에별로 의미가 없습니다. 또한 다른 언어로 제공되는 언어 기능 (유형 시스템, OOD 지원)이 있으므로 C를 사용하여 새로운 언어를 설계하지 않고 C로 구현할 수없는 경우가 있습니다 ( '새로운 언어'가있는 이유)
Sprague

당신은 알고있다. 내 의견이이 게시물과 어떤 관련이 있는지 더 이상 볼 수 없습니다. : P
Chris Becke

Cuda는 한동안 C ++을 지원했습니다.
Aryeh Leib Taurog
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.