[oop] 기능 프로그래밍이 GoF 디자인 패턴을 대체합니까?

작년에 F #OCaml을 배우기 시작한 이후 , 디자인 패턴 (특히 Java)이 명령형 언어에서 누락 된 기능에 대한 해결책이라고 주장하는 수많은 기사를 읽었습니다. 내가 찾은 한 기사 는 상당히 강력한 주장을합니다 .

내가 만난 대부분의 사람들 은 Gang of Four (GoF) 의 Design Patterns 책 을 읽었습니다
. 자존심있는 프로그래머라면 누구나이 책이 언어에 구애받지 않고 사용하는 언어에 관계없이 소프트웨어 엔지니어링에 일반적으로 적용되는 패턴을 알 수 있습니다. 이것은 고귀한 주장입니다. 불행히도 그것은 진실에서 멀리 떨어져 있습니다.

기능적 언어는 매우 표현력이 뛰어납니다. 기능적 언어에서는 언어가 너무 높기 때문에 디자인 패턴이 필요하지 않으므로 디자인 패턴을 모두 제거하는 개념으로 프로그래밍해야합니다.

FP (Functional Programming)의 주요 기능에는 1 급 값, 카레, 불변 값 등의 기능이 포함됩니다. OO 디자인 패턴이 이러한 기능 중 하나에 가깝다는 것은 분명하지 않습니다.

또한 OOP를 지원하는 기능 언어 (예 : F # 및 OCaml)에서는 이러한 언어를 사용하는 프로그래머가 다른 모든 OOP 언어에서 사용할 수있는 것과 동일한 디자인 패턴을 사용한다는 것이 분명해 보입니다. 실제로 지금은 매일 F #과 OCaml을 사용하고 있으며, 이러한 언어에서 사용하는 패턴과 Java로 작성할 때 사용하는 패턴간에 뚜렷한 차이가 없습니다.

함수형 프로그래밍이 OOP 디자인 패턴이 필요 없다는 주장에 대한 진실이 있습니까? 그렇다면 전형적인 OOP 디자인 패턴과 그에 상응하는 기능의 예를 게시하거나 연결할 수 있습니까?



답변

인용 한 블로그 게시물의 소유권 주장이 약간 과장되었습니다. FP는하지 않습니다 제거 디자인 패턴에 대한 필요성을. “디자인 패턴”이라는 용어는 FP 언어에서 동일한 것을 설명하는 데 널리 사용되지 않습니다. 그러나 그들은 존재합니다. 함수형 언어는 “문제 X가 발생하면 Y처럼 보이는 코드 사용”과 같은 모범 사례 규칙을 많이 가지고 있으며 이는 기본적으로 디자인 패턴입니다.

그러나 대부분의 OOP 특정 디자인 패턴은 기능적 언어와 관련이없는 것이 맞습니다.

나는 디자인 패턴 이 일반적으로 언어의 단점을 보완하기 위해 존재 한다고 말하는 것이 논쟁의 여지가 없다고 생각합니다 . 그리고 다른 언어가 같은 문제를 사소하게 해결할 수 있다면 다른 언어에는 디자인 패턴이 필요하지 않습니다. 해당 언어의 사용자는 해당 언어의 문제 아니기 때문에 문제 있음을 인식하지 못할 수도 있습니다 .

다음은 Gang of Four가이 문제에 대해 말한 내용입니다.

프로그래밍 언어의 선택은 자신의 관점에 영향을주기 때문에 중요합니다. 우리의 패턴은 스몰 토크 / C ++ 레벨 언어 기능을 가정하며, 그 선택에 따라 쉽게 구현할 수있는 것과 불가능한 것이 결정됩니다. 절차 언어를 가정하면 “상속”, “봉지”및 “다형성”이라는 디자인 패턴을 포함했을 수 있습니다. 마찬가지로 일부 패턴은 덜 일반적인 객체 지향 언어에 의해 직접 지원됩니다. 예를 들어, CLOS에는 방문자와 같은 패턴의 필요성이 줄어드는 다중 방법이 있습니다. 실제로 스몰 토크와 C ++ 사이에는 충분한 차이가있어 어떤 패턴은 다른 언어보다 한 언어로 더 쉽게 표현 될 수 있습니다. (예를 들어 반복자 참조)

(위는 4 페이지 3 항 디자인 패턴 소개 책에서 인용 한 것입니다)

함수형 프로그래밍의 주요 기능에는 일류 값, 카레, 불변 값 등의 함수가 포함됩니다. OO 디자인 패턴이 이러한 기능 중 하나에 가깝다는 것은 분명하지 않습니다.

일류 함수의 근사치가 아닌 경우 명령 패턴은 무엇입니까? 🙂 FP 언어에서는 단순히 함수를 다른 함수의 인수로 전달합니다. OOP 언어에서는 클래스에서 함수를 마무리해야합니다. 클래스에서 인스턴스화 한 다음 해당 함수를 다른 함수로 전달할 수 있습니다. 효과는 동일하지만 OOP에서는 디자인 패턴이라고하며 훨씬 더 많은 코드가 필요합니다. 카레하지 않으면 추상 팩토리 패턴은 무엇입니까? 한 번에 조금씩 매개 변수를 함수에 전달하여 마지막으로 호출 할 때 어떤 종류의 값을 내뿜는 지 구성하십시오.

따라서 더 강력하고 사용하기 쉬운 대안이 있기 때문에 여러 GoF 디자인 패턴이 FP 언어로 중복 렌더링됩니다.

그러나 FP 언어로 해결 되지 않은 디자인 패턴이 여전히 있습니다. FP는 싱글 톤과 동일합니까? (단일 톤은 일반적으로 사용하기에 끔찍한 패턴이라는 점을 무시하십시오.)

그리고 그것은 두 가지 방식으로 작동합니다. 내가 말했듯이 FP에는 디자인 패턴도 있습니다. 사람들은 보통 그것들을 그렇게 생각하지 않습니다.

그러나 모나드를 가로 질러 갔을 수도 있습니다. “글로벌 상태를 다루는”디자인 패턴이 아니라면 무엇입니까? 이는 OOP 언어에서 매우 단순한 문제이므로 동등한 디자인 패턴이 존재하지 않습니다.

당신이 단지 무엇 때문에, “그 소켓에서 읽기” “정적 변수를 증가”, 또는 위해 우리는 디자인 패턴이 필요하지 않습니다 .

모나드를 디자인 패턴이라고 말하는 것은 일반적인 연산을 수행하는 정수를 말하는 것과 같이 터무니없고 제로 요소는 디자인 패턴입니다. 아닙니다. 모나드는 디자인 패턴이 아닌 수학적 패턴 입니다.

(순수한) 기능적 언어에서는 모나드 “디자인 패턴”또는 동일한 것을 허용하는 다른 방법으로 문제를 해결하지 않으면 부작용과 변경 가능한 상태가 불가능합니다.

또한 OOP를 지원하는 기능 언어 (예 : F # 및 OCaml)에서는 이러한 언어를 사용하는 프로그래머가 다른 모든 OOP 언어에서 사용할 수있는 것과 동일한 디자인 패턴을 사용한다는 것이 분명해 보입니다. 실제로 지금은 매일 F #과 OCaml을 사용하고 있으며,이 언어에서 사용하는 패턴과 Java로 작성할 때 사용하는 패턴간에 뚜렷한 차이가 없습니다.

아마도 당신은 여전히 ​​필수적으로 생각하기 때문에? 많은 사람들이 평생 명령형 언어를 다룬 후에는 기능적 언어를 시도 할 때 그 습관을 포기하는 데 어려움을 겪습니다. (F #에서 문자 그대로 모든 함수는 기본적으로 C 프로그램을 사용하는 것처럼 문자열로 ‘let’문의 문자열이었고 모든 세미콜론을 ‘let’으로 바꿨습니다.)

그러나 또 다른 가능성은 OOP 언어의 디자인 패턴이 필요한 사소한 문제를 해결하고 있다는 사실을 깨닫지 못했을 수도 있습니다.

커리를 사용하거나 다른 함수에 대한 인수로 함수를 전달할 때 OOP 언어에서 어떻게 수행하는지 생각하고 중지하십시오.

함수형 프로그래밍이 OOP 디자인 패턴이 필요 없다는 주장에 대한 진실이 있습니까?

네. 🙂 FP 언어로 작업 할 때 더 이상 OOP 특정 디자인 패턴이 필요하지 않습니다. 그러나 여전히 MVC 또는 기타 비 OOP 관련 항목과 같은 일반적인 디자인 패턴이 필요하며 대신 새로운 FP 관련 “디자인 패턴”이 필요합니다. 모든 언어에는 단점이 있으며 디자인 패턴은 일반적으로 우리가 해결하는 방법입니다.

어쨌든 ML (최소한 개인적으로 좋아하는 학습 목적) 또는 Haskell 과 같은 “깨끗한”FP 언어 또는 Haskell 에서 손을 시험해 보는 것이 흥미로울 수 있습니다. 새로운 무언가에 직면 해 있습니다.


예상 한대로 몇몇 사람들은 “언어의 단점을 패치”하는 디자인 패턴에 대한 나의 정의에 반대했습니다.

이미 언급했듯이, 대부분의 디자인 패턴은 하나의 프로그래밍 패러다임 또는 때로는 하나의 특정 언어에 따라 다릅니다. 종종 패러다임 에만 존재 하는 문제를 해결합니다 (FP의 모나드 또는 OOP의 추상 팩토리 참조).

FP에 추상 팩토리 패턴이없는 이유는 무엇입니까? 해결하려는 문제가 존재하지 않기 때문입니다.

따라서 FP 언어에는없는 OOP 언어에 문제가 있으면 분명히 OOP 언어의 단점입니다. 문제를 해결할 수는 있지만 언어는 그렇지 않지만 문제를 해결하려면 상용구 코드가 필요합니다. 이상적으로, 우리는 프로그래밍 언어가 모든 문제 를 마술처럼 없애기 를 원합니다 . 여전히 존재하는 문제는 원칙적으로 언어의 단점입니다. 😉


답변

함수형 프로그래밍이 OOP 디자인 패턴이 필요 없다는 주장에 대한 진실이 있습니까?

함수형 프로그래밍은 객체 지향 프로그래밍과 다릅니다. 객체 지향 디자인 패턴은 함수형 프로그래밍에는 적용되지 않습니다. 대신, 기능적인 프로그래밍 디자인 패턴이 있습니다.

함수형 프로그래밍의 경우 OO 디자인 패턴 북을 읽지 않습니다. FP 디자인 패턴에 대한 다른 책을 읽습니다.

언어에 구애받지 않는 언어

완전히 아닙니다. OO 언어와 관련하여 언어에 구애받지 않습니다. 디자인 패턴은 절차 적 언어에는 전혀 적용되지 않습니다. 관계형 데이터베이스 디자인 컨텍스트에서는 거의 의미가 없습니다. 스프레드 시트를 디자인 할 때는 적용되지 않습니다.

전형적인 OOP 디자인 패턴과 그에 상응하는 기능?

위의 내용이 존재하지 않아야합니다. OO 코드로 다시 작성된 절차 코드를 요구하는 것과 같습니다. 음 … 원래 Fortran (또는 C)을 Java로 번역하면 번역 이상의 작업을 수행하지 않습니다. OO 패러다임으로 완전히 다시 쓰면 더 이상 원래 포트란이나 C와 같은 모양이 아닙니다. 인식 할 수 없습니다.

OO 디자인에서 기능적 디자인으로의 간단한 매핑은 없습니다. 그들은 문제를 보는 매우 다른 방법입니다.

함수형 프로그래밍 ( 모든 프로그래밍 스타일 과 마찬가지로 )에는 디자인 패턴이 있습니다. 관계형 데이터베이스에는 디자인 패턴이 있고 OO에는 디자인 패턴이 있으며 절차 적 프로그래밍에는 디자인 패턴이 있습니다. 모든 것은 디자인 패턴, 심지어 건축물의 아키텍처를 가지고 있습니다.

개념으로서의 디자인 패턴은 기술이나 문제 영역에 관계없이 영원한 구축 방법입니다. 그러나 특정 디자인 패턴은 특정 문제 영역 및 기술에 적용됩니다.

자신이하는 일을 생각하는 사람은 누구나 디자인 패턴을 발견 할 것입니다.


답변

언어와 패턴 사이의 긴밀한 연계에 대한 Brian의 의견은 요점입니다.

이 토론에서 빠진 부분은 관용구의 개념입니다. James O. Coplien의 저서 “Advanced C ++”는 큰 영향을 미쳤습니다. 크리스토퍼 알렉산더와 이름없는 칼럼 을 발견하기 오래 전에 (알렉산더를 읽지 않고는 패턴에 대해 현명하게 이야기 할 수 없다), 그는 언어를 진정으로 배우는 관용구 숙달의 중요성에 대해 이야기했다. 그는 예를 들어 C에서 문자열 복사를 사용했습니다. while(*from++ = *to++);이 기능은 언어 기능 (또는 라이브러리 기능)이 누락 된 것에 대한 반창으로 볼 수 있지만 실제로 중요한 것은 생각보다 표현력이 더 크다는 것입니다. 그 부분.

그것이 우리의 의도를 더 간결하게 표현할 수 있도록 패턴과 언어가 시도하는 것입니다. 생각의 단위가 풍부할수록 당신이 표현할 수있는 생각이 더 복잡해집니다. 시스템 아키텍처에서 비트 트위들 링에 이르기까지 다양한 규모의 풍부하고 공유 된 어휘를 사용하면보다 지능적인 대화와 우리가해야 할 일에 대한 생각을 가질 수 있습니다.

또한 개인으로서도 배울 수 있습니다. 운동의 요점은 어느 것입니까? 우리는 결코 우리 자신을 생각할 수 없었던 것들을 이해하고 사용할 수 있습니다. 언어, 프레임 워크, 라이브러리, 패턴, 관용구 등은 모두 지적 재산을 공유 할 수 있습니다.


답변

GoF 책은 명시 적으로 OOP와 관련이 있습니다. 제목은 디자인 패턴-재사용 가능한 객체 지향 소프트웨어의 요소 (강조 광산)입니다.


답변

Peter Norvig의 동적 프로그래밍의 디자인 패턴 은 ‘기능적’대신 ‘동적’언어 (중복이 있음)에 대해이 일반적인 주제를 신중하게 다루었습니다.


답변

이 주제를 논의하는 또 다른 링크가 있습니다 : http://blog.ezyang.com/2010/05/design-patterns-in-haskel/

Edward의 블로그 게시물에서 Edward는 Haskell과 관련하여 23 개의 원본 GoF 패턴을 모두 설명합니다.


답변

이것을 “디자인 패턴”(일반적으로)과 “FP 대 OOP”수준에서 보려고하면 찾을 수있는 답변이 가장 어둡습니다.

하지만 두 축의 수준을 한 단계 더 높이고 특정 디자인 패턴특정 언어 기능 및 상황이 더 명확 해지는 것을 고려하십시오 .

예를 들어, Visitor , Strategy , CommandObserver 와 같은 일부 특정 패턴 은 대수적 데이터 유형 및 패턴 일치 , 클로저 , 퍼스트 클래스 함수 등 의 언어를 사용할 때 확실히 변경되거나 사라집니다 . GoF 서적의 일부 다른 패턴 그래도 ‘고착’합니다.

일반적으로 시간이 지남에 따라 새로운 (또는 인기있는 언어) 언어 기능으로 특정 패턴이 제거되고 있다고 말할 수 있습니다. 이것은 언어 디자인의 자연스러운 과정입니다. 언어의 수준이 높아짐에 따라 이전에는 예제를 사용하여 책에서만 호출 할 수 있었던 추상화가 특정 언어 기능 또는 라이브러리의 응용 프로그램이되었습니다.

(제외 : 여기 내가 작성한 최근 블로그 가 있는데, 여기에는 FP 및 디자인 패턴에 대한 자세한 토론 링크가 있습니다.)