Object Oriented Programming이 복잡성에 대한 해결책이라고 생각하십니까? 왜? 이 주제는 약간 논란의 여지가 있지만 여기 전문가들로부터 왜 대답했는지 알고 싶습니다!
Object Oriented Programming이 복잡성에 대한 해결책이라고 생각하십니까? 왜? 이 주제는 약간 논란의 여지가 있지만 여기 전문가들로부터 왜 대답했는지 알고 싶습니다!
답변:
복잡성에 대한 해결책은 없습니다.
"신화적인 남자-월"에서 Fred Brooks는 프로그래밍에서 우연한 것과 본질적인 복잡성의 차이점에 대해 이야기합니다. 우발적 인 복잡성은 아이디어를 직접 표현할 수 없기 때문에 언어로 추가 코드를 작성하고 테스트해야하는 것과 같은 도구 및 방법으로 인해 발생합니다. 새로운 방법과 기술은 우발적 인 복잡성을 줄일 수 있습니다. 언어와 도구가 향상 되었기 때문에 25 년 전보다 더 빠르고 더 나은 프로그램을 작성할 수 있습니다.
본질적인 복잡성은 우리가 프로그래밍으로하는 것이 본질적으로 복잡하고 돌이킬 수없는 복잡성이 있다는 사실에서 비롯됩니다. 이 문맥에서 "필수"는 "매우 필요함"이 아니라 "사물의 본질과 관련됨"을 의미한다.
따라서 그는 총알이 없을 것이며 소프트웨어 작성은 계속 어려울 것이라고 주장했다.
나는 그의 책을 읽을 것을 강력히 권장합니다. 특히, "Silver Bullet"이라는 추가 에세이와 함께 Silver Anniversary 에디션을 추천합니다. 그는 복잡성에 대한 제안 된 솔루션을 검토하고 그 영향을 고려합니다. (가장 효과적인 것은 수축 포장 소프트웨어입니다. 복잡한 것을 한 번 작성하고 수천 또는 수백만 부를 판매하십시오.)
이제 객체 지향 프로그래밍은 올바른 작업을 수행 할 때 추상화를 생성하고 복잡성을 숨겨줍니다. 클래스의 객체에는 구현의 복잡성을 신경 쓰지 않고 추론 할 수있는 특정 동작이 정의되어 있습니다. 적절하게 작성된 수업은 서로의 연계성이 낮으며, 분할 정복은 복잡한 문제를 해결할 수있는 훌륭한 방법입니다. 또한 서로 밀접한 관련이있는 일련의 기능과 데이터라는 점에서 응집력이 높습니다.
곧 더 나은 답변을 얻을 것으로 기대하지만 간단한 답변은 다음과 같습니다.
OOP는 전 세계의 다른 모든 것을 모델링하는 방식에 더 가까운 방식으로 소프트웨어를 모델링함으로써 복잡성을 돕습니다 *. 벽 객체와 상호 작용하는 볼 객체를 이미지화하는 것이 현실 세계와 상호 작용하는 방식에 더 가깝기 때문에 동일한 일을 수행하는 일련의 루틴 및 데이터 구조를 상상하는 것보다 일반적으로 쉽습니다.
아무것도 복잡성을 '해결'할 수 없기 때문에
OOP의 현재 주류 정의는 복잡성을 관리하는 좋은 솔루션이 아니라고 생각합니다.
당신이 그 뿌리로 돌아 가면, Alan Kay가 "작은 입술"의 영향을 많이 받았다고 생각합니다.
Lisp는 주류 채택으로 손상되지 않았기 때문에 핵심 가치를 보존 할 수있었습니다. 그래서 lisp가이 복잡성 문제를 어떻게 해결하는지 살펴보면 약간의 통찰력을 얻을 수 있으며 OOP가 복잡성을 처리하는 데 얼마나 유용한 지 판단하는 기준으로 사용할 수 있습니다.
SICP 의 "강의 3a : Henderson Escher 예"의 끝을 보면 Hal Abelson은 작업을 더 작은 하위 작업으로 나누지 않고 추상화 계층을 만들어서 복잡성을 관리 할 것을 제안합니다. 최상위 레벨에서는 솔루션을 낮은 레벨의 추상화로 볼 때 복잡한 문제에 대한 솔루션을 표현합니다.
OOP는 원래 이러한 추상화 계층을 만드는 메커니즘으로 의도 된 것 같습니다.
불행하게도 오늘날 OOP는 스파게티 코드 / 구조를 작성하는 데 사용됩니다.
예를 들어 FPS 멀티 플레이어 게임을 구성하겠습니다.
최고 수준에서 게임은 많은 플레이어가 맵 주위를 실행하고 무기를 사용하여 서로를 쏘아 작동합니다.
다음 단계에서는지도와 무기, 플레이어에 대해 이야기해야합니다. 아마도 우리는 그것들을 게임의 세계에서 상호 작용하는 물리적 인 물건으로 말할 수 있습니다.
다음 단계에서는 객체가 물리적으로 어떻게 상호 작용하는지 (움직임, 충돌 등)에 대해 이야기 할 수 있습니다.
그리고 등등.
이것이 의미하는 것은 (그리고 SICP에서 인용하고 있습니다.) 각 계층에서 우리는 특정 특정 문제를 해결할뿐만 아니라 우리가 직면 한 문제 근처에서 일종의 문제를 해결한다는 것입니다. 다시 해결하려고합니다. 따라서 문제 설명에 약간의 변화가 있다면 해결책에 약간의 변화 만 필요합니다.
따라서 OOP를 사용하는 현명한 방법은 각 추상화 레벨에서 추상화 계층을 작성하는 것입니다. 바로 아래 레벨에서 "개체"를 사용하여 당면한 문제를 해결하십시오.
강의에서 인용 한 내용은 다음과 같습니다. http://www.youtube.com/watch?v=CYtrfncMqHQ
평소처럼 나는 모든 사람에 동의하지 않습니다. 복잡성을 관리하기위한 도구를 제공하는 것 외에도 OOP는 부적절하고 수학적으로 가짜 패러다임이기 때문에 엄청난 복잡성을 만듭니다. OOP로 모델링 할 수없는 OOP로 모델을 모델링하려고 시도하는 것은 프로그래머에게 혼란을주지 않습니다.
필자의 견해로는 여기서 중요한 작업은 Meyer의 객체 지향 소프트웨어 구성입니다. 여기에는 중요한 것으로 간주되는 요구 사항 인 공개 폐쇄 원칙 (Open-Closed Principle)이 포함됩니다. 이것은 물건이 확장을 위해 열려 있어야하지만 동시에 사용하기 위해 닫혀 있어야한다고 말합니다.
Meyer는 Eiffel에 구현 된대로 이러한 요구 사항에서 Object Orientation을 도출합니다. 캡슐화는 폐쇄, 상속 개방성을 제공하며 언급 된 "것"이 클래스입니다.
나는 Meyer가 명백히 틀 렸기 때문에이 연구를 좋은 과학이라고 생각한다. 그리고 그의 작업의 질 때문에 오류를 지적하고 고칠 수있다.
오류는 모듈화의 클래스 또는 유형을 만드는 것입니다. 그것은 틀렸고, 아마도 그럴 것입니다. Meyer조차도 OOP가 하나보다 높은 arity의 관계를 처리 할 수 없다는 문제 (공분산 문제라고 함)를 인식했습니다 (즉, OOP는 속성에는 적합하지만 이진 관계에는 실패합니다). 에펠에서는이 문제로 인해 형식 시스템에서 소리가 나지 않았습니다!
해결책은 분명합니다. 모듈화 단위는 단일 유형보다 커야합니다. 여러 유형과 관련 방법으로 구성되어야합니다.
이 추상화 모델이 수학적 추상화 이론, 즉 범주 이론에 의해 뒷받침되는 것은 놀라운 일이 아닙니다. 유형은 범주의 객체이고 방법 (함수)은 화살표입니다.
이 모델에서는 여러 유형 의 표현이 일련의 기능으로 알려져 있습니다. 표현은 공개적으로 숨겨져 있으므로 캡슐화이지만 클래스가 아닌 모듈을 사용합니다.
SML (Standard Meta-Language) 및 Ocaml은이 모델을 직접 기반으로합니다. Ocaml에는 클래스와 OOP도 있습니다. OOP는 동적 바인딩이라는 속성을 디스패치하기 때문에 쓸모가 없습니다. 그러나 대부분의 실제 문제는 관계와 관련이 있으며 Ocaml에서 클래스가 많이 사용되지 않는 것은 놀라운 일이 아닙니다.
상속이 C ++ 표준 템플릿 라이브러리에서 거의 사용되지 않는 것은 놀라운 일이 아닙니다.
간단한 사실은 OOP가 복잡성을 처리 할 수있는 올바른 도구를 제공하지 않고, 실제로 간단한 문제를 처리 할 수있는 도구를 제공하지도 않고, 2 세대 프로그래머를 오도하고 혼란스럽게한다는 것입니다. 도움이되지 않는 한 OOP는 C, Fortran, Cobol이 피곤해지기 시작한 이래 프로그래밍에서 일어난 가장 악하고 나쁜 일입니다.
객체 지향 프로그래밍에는 1960 년대까지 추적 될 수있는 뿌리가 있습니다. 하드웨어와 소프트웨어가 점점 복잡해지면서 관리 효율성이 종종 문제가되었습니다. 연구원들은 분리 가능하고 재사용 가능한 프로그래밍 로직 단위를 강하게 강조함으로써 일반적인 문제를 해결하기 위해 소프트웨어 품질을 유지하는 방법과 객체 지향 프로그래밍을 부분적으로 개발했습니다 .
따라서, 객체 지향 프로그램은 프로그램이 수행 할 작업 (서브 루틴)의리스트로 보여지는 종래의 모델과 달리 상호 작용하는 객체의 집합으로 간주 될 수있다. OOP에서 각 개체는 메시지를 받고, 데이터를 처리하고, 다른 개체로 메시지를 보낼 수 있습니다. 각 개체는 고유 한 역할 또는 책임을 가진 독립적 인 '기계'로 볼 수 있습니다. 이러한 개체에 대한 작업 (또는 "방법") 은 개체 자체와 밀접한 관련이 있습니다.
http://en.wikipedia.org/wiki/Object-oriented_programming
다형성, 상속, 메시지 전달, 디커플링 및 캡슐화와 같은 객체 지향의 다른 기능과 함께 이러한 관심의 분리는 대규모 프로그램의 복잡성을 매우 효과적으로 관리 할 수있는 논리적이고 개념적 프레임 워크를 제공합니다.
소프트웨어 개발에는 많은 종류의 복잡성이 있습니다. 프로그래밍 수준에서 OOP는 개체와 클래스를 사용하여 문제 영역을 모델링함으로써 복잡성을 해결하려고합니다. 잘 알려진 전문가는 문제 해결은 문제를 나타내는 것이므로 솔루션 자체가 표현 자체라고 말합니다. 따라서 클래스를 사용한 추상화, 액세스 수정 자 및 메소드를 사용한 캡슐화, 관계 및 재사용을 지정하기위한 상속, 클래스 간의 관계 및 협업 설정의 구성, 유사한 오브젝트에서 서로 다른 동작의 결정을 단순화하는 수단으로 다형성을 통해 복잡성을 관리 할 수 있습니다.
소프트웨어 복잡성을 관리하는 다른 방법 (예 : 논리 (Prolog) 및 기능 (Haskell) 프로그래밍)도 있습니다.
프로그래밍보다 높은 수준에서는 OOP를 안내하기 위해 디자인 패턴과 원칙이 필요합니다. 따라서 OOP는 복잡성을 낮은 (코딩) 수준으로 관리하는 반면, 디자인 패턴 및 원칙과 같은 이러한 방법론은 솔루션의 디자인을 더 높은 (시스템 및 애플리케이션) 수준으로 안내하고 소프트웨어 개발 및 처리 복잡성을보다 관리하기 쉽게 만듭니다.
귀하의 질문에 대답하기 위해 OOP는 다른 많은 솔루션 중에서 복잡성을 처리하는 솔루션 일뿐입니다. 낮은 수준의 솔루션입니다. OOP를보다 높은 수준으로 이끌려면 디자인 패턴과 원칙이 필요합니다.
객체 지향 프로그래밍 은 필수적이고 선택적인 복잡성을 관리 하지만 그다지 감소하지는 않습니다.
Eric Steven Raymond가 The Art of Unix Programming 에서 제공 한 정의를 선호합니다 . 왜냐하면 필수, 선택 및 우연한 복잡성을 구분하기 때문입니다. http://www.faqs.org/docs/artu/ch13s01.html#id2964646
OOP는 필수 또는 선택적인 복잡성에 대해 아무 것도하지 않으며 프로그램 요구 사항의 기능입니다. 때로는 OOP로 더 우아한 디자인을 만들 수 있기 때문에 실수로 인한 복잡성에 영향을 줄 수 있습니다. 그러나 때로는 OOP를 사용할 때 디자인이 더 나쁩니다.
복잡한 문제는 기술을 통해 단순하게 만들 수 없으며 기술을 통해서만 관리 할 수 있습니다 .
OOP는 기술, 개념 및 문제에 접근하는 방법입니다.
OOP는 복잡성을보다 쉽게 관리 할 수 있는 디자인 을 시행 할 수있는 도구를 제공 하지만, 복잡성을 증가시키는 나쁜 디자인을 쉽게 가질 수 있습니다. 다시 말해, 올바르게 사용하지 않으면 기술로 인해 문제가 복잡해질 수 있습니다.
프로젝트의 성공 여부를 결정하는 다른 많은 측면 (예 : 프로젝트 관리 스타일, 문제 정의, 변경 관리 등)이 있습니다. 사용하는 기술 은 문제 를 관리 하는 데 얼마나 도움이 될지에 대해서만 관련 이 있습니다.
결국 객체 지향 프로그래밍은 복잡성 의 해결책 이 될 수 없습니다 . 관리 도구 일뿐입니다. (올바르게 사용 된 경우)
객체 지향 (일반적으로 사용되는)은 많은 상황에서 유용한 도구이지만 복잡성에 대한 충분한 솔루션은 아닙니다.
특히, 종종 많은 " 부수적 인 복잡성 "을 추가합니다 . 예 구현 상속을 둘러싼 복잡하고있다 "표준 기능"동등하게 suach ()와 hashCode ()이 주제에 스튜어트 Halloway로 등 좋은 프리젠 테이션을 많이 제공 할 필요 : "은 단순 쉽지 않다 "
대부분의 언어로 된 객체는 또한 많은 변경 가능한 상태 를 캡슐화하는 경향이 있습니다 . 동시 세계에서는 점점 더 나쁜 디자인 결정처럼 보이기 시작합니다. 다시 Rich Hickey 의 흥미로운 비디오 는 객체의 정체성과 상태의 차이점과이 둘을 혼동하는 것이 어떻게 실수 일 수 있는지 살펴 봅니다.
객체 지향 프로그래밍은 문제를 표현하는 방법입니다. 그 자체로는 다른 프로그래밍 패러다임보다 덜 복잡하지 않습니다. 잘 설계된 OOP 시스템은 복잡성을 관리하고 줄이지 만, 필요 이상으로 훨씬 더 복잡하고 모든 것을 방해하는 시스템을 설계하는 것은 매우 쉽습니다.
종종 C ++에 대해 말했듯이 OOP는 자신을 걸 수있는 충분한 밧줄을 제공합니다.
OOP는 해결책을 시도합니다.
복잡성을 관리하는 가장 좋은 방법은 추상화를 만드는 것입니다. 컬렉션에서 작동하는 인식 가능한 함수를 사용하여 데이터를 유용한 컬렉션으로 변환 할 수 있으면 컬렉션을 개별 "사물"로 생각할 수 있습니다. 이것이 클래스와 메소드의 기초입니다. 이와 관련하여 올바르게 설계된 OOP는 복잡성을 관리하는 데 도움이 될 수 있습니다.
누군가가 OOP를 사용하여 코드 재사용 문제를 해결할 수 있다고 결정했습니다. 왜 바퀴를 재발 명합니까? 다른 사람 이이 문제를 해결하기 위해 많은 노력을 기울 였다면, 그들이 한 일을 활용하고, 특정 프로젝트에 필요한 조정 사항을 추가하십시오! 상대적으로 적은 노력으로 강력하고 정교한 응용 프로그램을 만들었습니다. OO 프로그래머는 매우 생산적인 프로그래머가 될 수 있습니다.
결과적으로 현대의 OO 프로그래머는 "마법사의 견습생"이되어 몇 줄의 "접착제"가있는 크고 다루기 힘든 많은 라이브러리를 묶어 작동합니다. 소르 타. 킨다 대부분의 경우 이 라이브러리를이 라이브러리와 함께 사용할 경우 부작용이 있습니까? 아마도. 그러나 누가 그 라이브러리에 포함 된 코드를 파헤칠 시간이 있습니까? 특히 라이브러리가 진화 할 때. 결과적으로 프로그래머는 해당 라이브러리의 소수의 클래스와 메소드가 필요한 부풀어 오른 응용 프로그램으로 끝나지 만 응용 프로그램은 필요하지 않은 모든 기타 항목의 가중치를 가져야합니다.
결과적으로 필요한 것보다 훨씬 더 복잡해집니다.
기능을 분리하려는 복잡성을 처리하는 또 다른 메커니즘입니다. 한 곳에서 모든 데이터 액세스 기능을 원합니다. 한 곳에서 모든 사용자 인터페이스 기능을 원합니다. 한 곳에서 모든 컨트롤러를 원합니다. 따라서 기능의 다른 부분을 관리하는 다른 클래스를 만듭니다. 여태까지는 그런대로 잘됐다. 그리고 이것은 어느 정도까지 확장됩니다. 데이터 액세스에 능숙한 개발자는 해당 클래스를 작성할 수 있고, 사용자 인터페이스 사람들은 사용자 인터페이스 클래스 등을 작성할 수 있습니다. 모두 훌륭합니다.
다른 사람이 작성한 것을 유지해야 할 때까지.
예, 모든 데이터 액세스 기능이 여기에 있다는 것을 아는 것이 좋습니다. 그러나 무엇이 그들을 부르는가?
이 메소드는 해당 클래스에서 해당 메소드를 호출합니다. 그러나 클래스 정의를 보면 그 이름을 가진 방법이 없습니다. 아, 그것은 상속 체인에서 하나 또는 두 개의 다른 계층에서 상속되었습니다. 잠시만 기다려주세요. 그 클래스는 인터페이스를 구현 했습니까? 해당 인터페이스를 구현하는 클래스는 몇 개입니까? 그리고 우리는 런타임에 클래스 인스턴스를 "함께 연결"하기 위해 복잡한 런타임 시스템을 사용하고 있습니까? 해당 인터페이스를 구현하는 어떤 클래스를 사용할 수 있습니까?
정확한 일을 수행하는 작고 별개의 방법이 많이 있습니다. 그러나 이것은 다른 클래스에서 이것을 호출합니다. 어떤 클래스를 다른 클래스에서 호출합니다. 또 다른 클래스에서 하나를 호출합니다. 추가 클래스에서 그 중 하나를 호출합니다. 특정 유형의 결과를 반환합니다. 특정 작업을 수행하기 위해 메소드를 호출해야합니다. 다른 유형의 결과를 반환합니다. 기타.
스파게티 코드라는 용어가 있습니다.
코드를 작성하는 데 필요한 매우 복잡한 시스템이 생깁니다. 따라서 Visual Studio, Eclipse 및 NetBeans와 같은 IDE입니다. 이들 모두 중요한 학습 곡선을 가지고 있습니다. 실제로, 그들 중 다수는 서로 다른 그룹에 의해 개발 된 여러 도구를 캡슐화 / 집계 할 수 있으며, 각각의 도구는 자신의 OWN 학습 곡선을 가지고 있습니다.
복잡성을 관리하고 있습니까?
코드 디버깅은 코드 작성보다 두 배나 어렵습니다. 이 것들 중 일부를 디버깅하는 행운을 빕니다. 특히 여러 라이브러리를 사용하는 경우 일종의 종속성 주입 시스템을 사용하여 런타임에 "함께 연결"됩니다.
요약 : OOP는 복잡성을 관리하는 데 도움이되는 유망한 도구처럼 보이는 기능을 제공합니다. 실제로는 결과 코드가 크게 부풀어 오르는 경향이 있으며 (링크 된 모든 라이브러리에서 필요한 조각 만 추출 할 수 없기 때문에) 코드를 탐색하기위한 정교한 도구가 필요합니다. 그것은 곧 유지 보수의 악몽이됩니다.
IMHO, 순손실입니다. 제거하는 것보다 더 복잡합니다. 그것은 당신이 없이는 매우 어려울 수도, 불가능할 수도있는 일들을 할 수있게 해줍니다. 그러나 모든 대형 프로젝트는 유지 관리 할 수없는 혼란으로 빠르게 발전합니다.
작동 방식을 이미 알고 있고 기억할 수있는 경우 유지 관리 기회가있을 수 있습니다.
이글 슨의 법칙을 적용하십시오. 6 개월 동안 보지 않은 코드는 다른 사람이 작성했을 수도 있습니다.
객체 지향 프로그래밍이 복잡성을 처리하는 데 도움이되는 이유는 다양한 방식 대신 특정 방식으로 코드를 작성해야하기 때문입니다. 작업 지향 프로그래밍이 훨씬 직관적이기 때문에 프로그래밍이 그렇게 시작되었습니다. 객체 지향은 효과적으로 이해하고 사용하기 위해 교육과 실습을 필요로하지만 프로그래밍을 특정 경로로 제한함으로써 교육을받은 사람들이 작성된 코드를 효과적으로 유지할 수 있습니다.
그것은 다른 어떤 방법보다 더 논리적이거나 현실적이지 않으며, 유사한 렌즈를 통해 문제를 해결하는 방법 일뿐입니다. 많은 기술 전문가가 직관의 복잡성을 처리하기 위해 직관적이지 않은 엄격한 방법론의 패러다임을 사용합니다.
복잡성을 처리하는 세 번째 방법은 함수형 프로그래밍이며, 앞으로 다른 새로운 방법도있을 것입니다.