객체 지향 프로그래밍에서 중요한 개념 중 하나는 캡슐화입니다. 그러나 최근 소프트웨어 세계는 함수형 프로그래밍과 같은 다른 패러다임을 선호하는 것처럼 보입니다.
캡슐화 및 기타 OOP 신조는 어떻습니까? 그들이 틀렸습니까?
OOP가 잘못 적용 되었습니까? 예를 들어 Alan Kay는 OOPSLA’97 기조 연설에서 “객체 지향이라는 용어를 발명했으며 C ++을 염두에 두지 않았다고 말할 수 있습니다.”라고 언급했습니다.
Joe Armstrong- “객체는 함수와 데이터 구조를 불가분의 단위로 묶습니다. 함수와 데이터 구조가 완전히 다른 세계에 속하기 때문에 이것이 근본적인 오류라고 생각합니다.”
답변
나는 당신이 여기에 빠진 함정은 프로그래밍 패러다임 (구조화, 객체 지향, 기능 등)에 대한 엄격한 정의가 있다고 생각하고 있다고 생각합니다.
두 명의 다른 개발자에게 OOP의 의미를 물어 보면 두 가지의 다른 답변을 얻을 수 있습니다. 예, 직업으로서 우리는 대학의 OOP 소프트웨어 엔지니어링 수업에서 다루는 캡슐화, 데이터 숨기기 등과 같은 몇 가지 공통 주제가 있음에 동의합니다.
그러나 현실에서는 상황이 그렇게 잘 정리되지 않았기 때문에 두 개발자가 서로 다른 두 가지 답변을하게됩니다. 아마도 그들은 OOP 개념을 다르게 표현하는 다른 언어의 전문가 일 것입니다. 언어 패러다임은 겹치는 경향이 있습니다. 2013 년 현재의 최신 분노는 클로저 또는 람다를 통해 객체 지향 언어로 기능 프로그래밍을 통합하는 것입니다. Java 8은 객체 지향적입니까, 기능적입니까? 나는 기능적인 대시로 객체 지향이라고 부릅니다. 다른 사람이 다르게 설명 할 수 있습니다.
OOP가 잘못 적용 되었습니까?
문제는 다양한 언어가 프로그래밍 개념을 다르게 표현한다는 것입니다. 한 언어는 OOP 개념을 생략하고 다른 언어는이를 포함하지만 다른 OOP 개념은 생략합니다. 언어는 일반적으로 다른 작업을 더욱 어렵게하면서 특정 유형의 작업을 쉽게 수행 할 수 있도록하기 위해 고안되었습니다. 그것은 옳고 그른 것이 아니며 피할 수없는 실제 트레이드 오프 일뿐입니다.
실제 세계는 교실 이 아닙니다 . 우리는 추상적 인 수준에서 개념적 프로그래밍 패러다임을 논의하거나 유용하기 위해 절충을 강요하는 실제 프로그래밍 언어에 대해 논의해야합니다. 프로그래밍 언어가 대부분 OOP의 추상 정의에 의해 정의되는 한 해당 버킷에 포함시킬 수 있습니다.
답변
그러나 최근 소프트웨어 세계는 함수형 프로그래밍과 같은 다른 패러다임을 선호하는 것처럼 보입니다.
논쟁의 여지가 있습니다. 첫째, OOP와 함수형 프로그래밍 외에 다른 패러다임을 보지 못하고 광범위하게 논의되었으므로 “다른 패러다임과 같은” 문구를 잊어 버릴 수 있다고 생각 합니다.
지난 몇 년 동안 함수형 프로그래밍이 인기를 얻은 이유는 다른 질문에서 자세히 논의되었으므로 반복하지 않겠습니다 ( 예 : 여기 또는 여기 참조 ). 그러나 제 생각에 이것은 “OOP가 큰 실수 였음”또는 “기능 대 OOP가 상호 배타적”이기 때문에 사람들이 도구 상자를 확장하고 두 세계를 최대한 활용하려는 것과 같습니다. 좋아, 확실히 강경 전문가가 서로 선호하는 전문가가 있지만 양쪽에서 그 사람들을 찾을 수 있습니다.
캡슐화 및 기타 OOP 신조는 어떻습니까? 그들이 틀렸습니까?
캡슐화에는 여러 가지 맛이 있습니다. 함수형 프로그래밍 언어 및 언어 구성은 특정 형태의 캡슐화, 객체 지향형을 제공합니다. 기능적 수단으로 캡슐화의 예를 찾고 있다면 클로저로 시작하십시오 .
“기타 교리”와 관련하여 : 아니요, 잘못된 것은 아니지만 대규모 병렬화와 같은 특정 시나리오의 경우 기능적 접근 방식이 더 나은 확장 성을 제공합니다. 잘 설계된 UI 프레임 워크를 만드는 것과 같은 다른 시나리오의 경우 OOP 접근 방식이 더 잘 확장 될 수 있습니다 (YMMV, 더 나은 예는 없습니다). 또한 대부분의 실제 시나리오에서는 특정 시스템이 얼마나 잘 확장되는지 가장 좋아하는 프로그래밍 패러다임으로 팀의 지식과 경험에 달려 있습니다.
OOP가 잘못 적용 되었습니까? 예를 들어 Alan Kay는 OOPSLA’97 기조 연설에서 “객체 지향이라는 용어를 발명했으며 C ++을 염두에 두지 않았다고 말할 수 있습니다.”라고 언급했습니다.
분명히 많은 사람들이 OOP를 잘못 적용하는 경우가 많지만 FP에서도 마찬가지입니다. John Mc Carthy (Lisp의 디자이너)가 함수형 프로그래밍에 대해 생각할 때 Javascript와 같은 것을 염두에두면 놀랄 것입니다 (자비, 저를 화나게하지 마십시오 .-)
Joe Armstrong- “객체는 함수와 데이터 구조를 불가분의 단위로 묶습니다. 함수와 데이터 구조가 완전히 다른 세계에 속하기 때문에 이것이 근본적인 오류라고 생각합니다.”
Erlang의 발명가는 몇 가지 좋은 주장을 가지고 있다고 생각하지만, 그는 또한 자신의 견해를 가지고 있으므로 그의 의견을 제시하고 자신의 의견을 제시하십시오. 이것에 대해 다른 아이디어를 가진 다른 많은 전문가들이 있습니다.
답변
물론이야:
struct Foo
{
string bar;
int bux;
}
나는 당신이 무슨 말을할지 알고 있습니다 : “그러나 그것은 또한 행동을 캡슐화하지 않습니다!” 저는 Joe Armstrong과 함께 일류 객체를 요구하지 않고 전체 프로그램이나 운영 체제를 작성할 수 있습니다. 리눅스는 그것을 증명합니다.
자바 스크립트 프로그래머는 일상적으로 클래스가 아닌 함수와 클로저의 상태와 동작을 캡슐화 합니다.
답변
여기서 주요 문제는 캡슐화가 엄격하게 정의 된 개념이 아니고 왜 유용하지 않다는 것입니다. 일부 연구를 통해 사람들이 캡슐화를 보는 방법에 대한 의견이 많으며 많은 사람들이 캡슐화를 추상화와 혼동하는 것으로 나타났습니다.
당신이 먼저 정의를 찾아 가고는 있다
캡슐화는 데이터를 조작하는 데이터와 기능을 하나로 묶는 개념입니다 …
이것이 당신의 정의라면, 대부분의 언어는 해당 데이터에서 작동하는 데이터와 함수를 클래스, 모듈, 라이브러리, 네임 스페이스 등으로 그룹화 할 수 있습니다.
그러나 나는 그 정의가 계속되는 것처럼 캡슐화의 주요 목적이 아니라고 주장합니다.
… 그리고 외부 간섭과 오용으로부터 안전합니다.
Wikipedia도 이에 동의 합니다.
일부 객체 구성 요소에 대한 직접 액세스를 제한하기위한 언어 메커니즘.
그러나 이제 “간섭 및 오용”의 의미와 데이터에 대한 직접 액세스가 제한되어야하는 이유를 묻어 야합니다. 두 가지 이유가 있다고 생각합니다.
먼저 데이터를 변경할 수있는 범위를 제한하는 것이 개발자에게 가장 큰 관심사입니다. 너무 자주 값을 설정하기 전 / 후에 논리가 있어야합니다. 그리고 가치를 설정할 수있는 장소의 수를 제한하는 것이 매우 중요합니다. OOP 언어에서는 클래스를 사용하여이를 수행 할 수 있습니다. “변경 가능”기능 언어에서 클로저는 동일한 목적을 제공합니다. 그리고 클래스 = 클로저를 알고 있기 때문에 , 가변 함수형 언어가 OOP와 다른 “패러다임”보다 논쟁의 여지가 있습니다.
그러나 불변의 언어는 어떻습니까? 변수를 변경하는 데 문제가 없습니다. 여기에 두 번째 문제가 있습니다. 바인딩 함수 및 데이터를 사용하면 해당 데이터를 유효한 상태로 유지할 수 있습니다. 에 대한 불변 구조가 있다고 상상해보십시오 Email
. 이 구조에는 단일 string
필드가 있습니다. 유형 값이있는 경우 Email
해당 필드에 유효한 주소가 포함되어야한다는 요구 사항이 있습니다. OOP의 캡슐화에서, 이것은 필드를 선언하고 방법 private
만 제공하며Get
constructor method
문자열로 전달 된 주소가 유효한 경우에만 성공합니다. 클로저와 비슷한 것. 이제 불변 언어의 경우 구조는 특정 기능을 통해서만 초기화 될 수 있으며 그러한 기능은 실패 할 수 있다고 말할 필요가 있습니다. 그리고 나는 그 기준에 맞는 언어를 알지 못합니다 (댓글을 가진 사람이 나를 밝힐 수 있습니다).
마지막 문제는 언어 “지원”캡슐화의 의미입니다. 한쪽에는 캡슐화를 적용 할 수있는 언어가 있으므로 캡슐화가 깨지면 코드가 컴파일되지 않습니다. 다른 한편으로, 언어는 캡슐화를 수행하는 방법을 제공 할 수 있지만 강제하지는 않으므로 개발자가 직접 강제로 실행합니다. 두 번째 경우에는 구조와 기능을 가진 모든 언어가 작동 할 수 있습니다. 역동적 인 언어와 Haskell이 떠 오릅니다. 그리고 스펙트럼의 반대편에 해당하는 언어가 많지 않다고 말할 것입니다. 리플렉션을 사용하여 객체의 캡슐화를 실제로 적용하는 C #조차도 우회 할 수 있습니다. 그러나 C #에서는 거대한 코드 냄새로 간주되며 C # 개발자는 기꺼이 그렇게하지 않습니다.