태그 보관물: design-patterns

design-patterns

OOP가 쉬워 지거나 어려워지고 있습니까? [닫은] 더 깨끗했습니다.

프로그래머에게 Object Oriented Programming의 개념이 소개되었을 때 흥미로워 보였고 프로그래밍이 더 깨끗했습니다. 이런 식으로

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);

그것은 자기 묘사 적 이름으로 이해하기가 더 쉬웠습니다.

그러나 이제는 데이터 전송 개체, 값 개체, 리포지토리, 종속성 주입 등과 같은 패턴을 가진 OOP가 더욱 복잡해졌습니다. 위의 내용을 달성하기 위해 여러 클래스 (예 : 추상, 팩토리, DAO 등)를 작성하고 여러 인터페이스를 구현해야 할 수 있습니다.

참고 : 공동 작업, 테스트 및 통합을보다 쉽게 ​​만드는 모범 사례에 위배되지 않습니다.



답변

OOP 자체는 처음부터 변하지 않았습니다. 그것에 대한 몇 가지 새로운 각도가 탐구되었지만 핵심 원칙은 여전히 ​​동일합니다. 어쨌든, 수년간 수집 된 집단 지식은 프로그래머의 삶을 어렵게 만드는 것이 아니라 쉽게 만듭니다. 디자인 패턴은 방해가되지 않습니다. 수년간의 경험에서 추출 된 표준 문제에 대한 솔루션의 도구 상자를 제공합니다.

그렇다면 오늘날 OOP를 사용하기 시작했을 때보 다 더 복잡하다고 생각하는 이유는 무엇입니까?

한 가지 이유는 노출되는 코드가 더 복잡해지기 때문일 수 있습니다. OOP가 더욱 복잡해 졌기 때문이 아니라 학습 래더를 발전시키고 더 크고 복잡한 코드 기반을 읽었 기 때문입니다.

또 다른 이유는 복잡성 패러다임이 변경되지 않았지만 일반 소프트웨어 프로젝트의 크기와 복잡성이 매우 좋을 수 있기 때문입니다. 20여 년 전에 서버 에서 개발자의 꿈이었던 고객 급 휴대폰에서 처리 능력을 사용할 수있게 되면서 일반 대중은 기본적으로 가장 저렴한 응용 프로그램까지 매끄러운 애니메이션 GUI를 기대하고 엔트리 레벨 데스크탑 PC는 더욱 강력 해졌습니다. 1980 년대의 “슈퍼 컴퓨터”보다 스몰 토크와 C ++의 초기부터이 기준이 높아진 것은 당연하다.

그리고 현대 응용 프로그램에서는 동시성 및 병렬 처리가 예외가 아니라 표준이라는 사실이 있습니다. 응용 프로그램은 종종 여러 컴퓨터간에 통신하여 전체 프로토콜 동물원을 출력하고 파싱해야합니다. OOP는 조직적 패러다임으로서 훌륭하지만 다른 패러다임과 마찬가지로 한계가 있습니다. 예를 들어 동시성에 대한 많은 추상화를 제공하지 않습니다 (대부분의 구현은 다소 사후에 고려되거나 라이브러리에 완전히 아웃소싱됩니다) 파서를 작성하고 데이터를 변환하는 가장 좋은 방법은 아닙니다. 최신 프로그래밍은 종종 OOP 패러다임의 한계에 부딪치며 디자인 패턴은 지금까지만 가능합니다. (몸소, 패러다임이 이러한 솔루션을 즉시 제공한다면 패러다임이 이러한 문제에 대해 더욱 표현력이 좋으며 표준 솔루션이 분명 할 것입니다. 메소드 상속은 OOP의 핵심 기능이기 때문에 메소드 상속을 설명하는 디자인 패턴이 없습니다. 그러나 OOP는 객체를 다형성 및 투명하게 구성하는 명백한 자연적인 방법을 제공하지 않기 때문에 팩토리 패턴이 있습니다.)

이 때문에 대부분의 최신 OOP 언어는 다른 패러다임의 기능을 통합하여보다 표현력이 뛰어나고 강력하지만 복잡해집니다. C #은 이에 대한 주요 예입니다. 명백한 OOP 루트를 가지고 있지만 델리게이트, 이벤트, 형식 유추, 변형 데이터 형식, 특성, 익명 함수, 람다 식, 제네릭 등의 기능은 다른 패러다임, 특히 기능적 프로그래밍에서 비롯됩니다. .


답변

아니요, 더욱 과도하게 엔지니어링되고 있습니다. 그리고 당신은 SO C ++ 채팅에서 우리가 Java 코드에서 보는 AbstractSingletonFactoryProxyBeanBridgeAdapterManagers에 대해 종종 농담합니다.

그러나 좋은 코드는이 속성을 나타내지 않습니다. 좋은 코드에서는 여전히 말할 수 있습니다.

std::stack<int> s;
s.push(5);
s.pop();

답변

언급 한 “복잡성”문제는 OOP와 관련이 없다고 말할 수 있습니다. 우려를 분리하는 것과 더 관련이 있습니다.

몇 년 전에 도메인 클래스가 데이터베이스에서 자체적으로로드를 담당하는 시스템을 작업했습니다.

var userId = Request.QueryString["UserID"].ToInt();
var user = new User(userId);
user.Name = ...;
...
user.Save();

이것은 매우 명확한 코드입니다. 이것을 이해하는데 아무런 문제가 없습니다. 그러나 문제는 코드를 단위 테스트하는 것입니다. 즉, User데이터베이스에서 클래스를로드하지 않고 클래스를 어떻게 단위 테스트 합니까? 그리고 데이터베이스에 액세스하지 않고이 웹 요청 처리 코드를 어떻게 테스트합니까? 단순히 불가능합니다.

그렇기 때문에 리포지토리와 같은 패턴을 사용하여 도메인 로직을 처리하는 책임을 데이터 저장소에 실제로로드하고 저장하는 기능과 사용자로부터 분리해야합니다. IOC는 커플 링을 줄이고 코드를 더 테스트 가능하게 만드는 데 도움이됩니다.

우리가 작성한 예제로 돌아 가면 주식을 만든 후에 어떻게 할 것입니까? 데이터베이스에 저장

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);
this.StockRepository.Add(stock);

빨간 것! OOP의 진행 중에는 더 힘들어 야한다는 움직임이 없습니다. 불행히도, 데이터 액세스 코드에 OR 매퍼를 사용하기로 선택하면 OR 매퍼가 시스템 작성 방법을 제한하는 문제가 발생할 수 있습니다. 그러나 그것은 또 다른 문제입니다.

이러한 패턴을 처음 사용하는 경우 새로운 스타일의 프로그래밍을 배워야 할 수도 있습니다. 그러나 이러한 스타일의 프로그래밍은 구식 OOP 프로그래밍보다 어렵지 않습니다.


답변

둘 다. 우리의 문제는 실제로 바뀌지 않았습니다. 허용 가능한 코드에 대한 막대가 높아졌습니다.

위의 내용을 달성하기 위해 여러 클래스 (예 : 추상, 팩토리, DAO 등)를 작성하고 여러 인터페이스를 구현해야 할 수 있습니다.

당신은하지 않는 그렇게 할 수 있습니다. 그러나 그렇지 않으면 문제가 발생합니다. 항상 거기에 있었던 문제. 그러나 프로그래머는 이러한 문제를 식별하고 필요한 경우 완화 할 수있는 메커니즘을 제공하기 위해 충분한 경험을 가지고 있습니다. 우리는 이것에 대해 더 많이 배우고 더 나은 솔루션을 제시합니다 (예 : 싱글 톤에 대한 프로그래머의 견해 참조).

그러나 프로그래머를 OO (또는 그 문제에 대한 것)에 소개하면 예외적 인 상황에서 광택을내는 경향이 있음을 알아야합니다. 행복한 길을 설명하는 것이 더 쉬우 며 초보자가 그만두면 나머지 부분에 대해 걱정할 수 있습니다. 은 총알이 없습니다. 그래서, 나는 목가적 인 망상이 깨질 때 상황이 항상 더 어려워 보일 것이라고 생각합니다 …


답변

“OO 소개”예제는 실제 응용 프로그램보다 훨씬 간단합니다. 위의 목표를 달성하려면 하나의 수업 만 필요합니다. 문제는 많이하지 않는다는 것입니다. ActiveRecord와 같은 일부 디자인 패턴은 밀접하게 접근하려고하지만 최종적으로 사소하지 않은 예제는 둘 이상의 클래스를 갖습니다. 괜찮습니다.


답변

오늘날 OO를 사용하는 프로그래밍 언어는 계속 변화하는 복잡한 요구 사항과 환경을 충족시키기 위해 노력하고 있습니다. OO를 사용하면 채택자가 다양한 수준의 복잡성을 숨길 수 있으므로 (다른 기능 중에서도) 코딩이보다 명확하고 이해하기 쉽습니다. 그러나이 기능이 항상 사용 가능한 것은 아닙니다. 귀하의 예에서 OO를 사용하면 컬렉션의 항목을 관리하는 방법을 제공하여 일부 세부 정보를 숨길 수 있으며 “AddItem”메서드를 사용하여 해당 항목을 유지할 수도 있습니다. 복잡성을 숨기려는 노력으로 인해 사용하기 쉽고 재사용 가능한 프레임 워크가 생겨 더 간단 해집니다. 예를 들어, 많은 ORM 구현을 사용하면 프로그래머가 SQL 세부 사항을 쓰지 않고도 데이터베이스와 통신 할 수 있습니다. 이것은 실제로 강력하며 개발자에게 더 간단합니다.

당신이 말하는 패턴은 바로 그 것입니다. 그들은 당신의 인생을 더 쉽게 만들어 줄 것입니다. 그러나 그들을 채택하고 조정하는 것은 당신에게 달려 있습니다. 더 많은 작업이 필요하다는 사실은 더 많은 혜택을 얻기 때문입니다. 페라리에 더 많은 돈을 지불하는 것과 같습니다. 엑스트라를 원하면 지불하십시오. 따라서 여러 서버와 다른 백엔드 데이터베이스에서 실행할 수있는 확장 가능한 N-Tier 솔루션을 구축하기로 결정한 경우 비용이 발생합니다. 응용 프로그램에 이러한 복잡성이 필요하지 않은 경우 추가 부분을 무시하고 필요에 맞는 가장 간단한 솔루션 (KISS & YAGNI)으로 넘어갑니다.

결론적으로, OOP 개념 자체가 점점 복잡해지고 있다고 생각하지 않습니다. 우리 OOP 사용자는 다른 방식으로 그것을 사용할 수 있습니다.


답변

짧은 대답 : 예. 더 어려운 문제를 다루기 때문입니다.

Long Answer (강하게 치우침) : 나에게 디자인 패턴은 일반적으로 일부 패러다임이 주어진 영역에 문제가 있음을 나타냅니다. OOP 패턴은 OOP의 문제를 처리하고 (하위 레벨에서 Java 패턴은 Java의 문제를 처리), FP 패턴은 FP 등의 문제를 처리합니다.

프로그래밍하는 동안 우선 순위가 다를 수 있습니다. 올바른 프로그램을 원할 수도 있고, 시장 진입 시간을 단축하고, 가장 빠른 프로그램을 가능하게하거나, 장기 유지 관리 가능성 또는 새로운 직원에 의한 즉각적인 유지 관리 가능성을 원할 수 있습니다. 덤불에 따라 당신은 크게 다를 것입니다-발전소의 컨트롤러를 프로그래밍하는 경우 처음부터 올바르게하고 싶을 때마다 버그를 수정하지 않으려 고합니다 ( “누를 때마다 붕괴가 발생합니까 Ctrl+Alt+Del?”). HPC를 사용하는 경우 논리는 비교적 간단하지만 가능한 빨리 실행하고 싶습니다. 또한 일부 패러다임은 특정 문제 (예 : AI 및 논리 프로그래밍, 데이터 및 관계형 데이터베이스)에 더 잘 맞습니다.

OOP는 간단한 경우에 ‘너무 좋아’확장하고 “실제 라이브 모델링”이야기입니다. OOP I에 대한 첫 번째 책에서 예를 읽고 거기에 수업이었다 Person, Employee그리고 Manageris-a의 관계. 지금까지는 좋지만 직원이 관리자로 승진하면 어떻게됩니까?

반면에 다른 패러다임은 처음에는 어려운 교훈이 있습니다-예를 들어 불변의 변수를 가진 FP OOP보다 어렵지 않습니다. 순수한 기능 테스트는 쉽지 않으며 Haskell / Scala /에는 테스트를 생성하는 도구가 있습니다.

추신. 예-답변은 OOP에 대해 편향되어 있으며 어느 정도 확장하면 OOP에 ‘반응’한다는 것을 인정합니다. OOP는 그 용도가 있지만 내 의견으로는 유일한 해결책은 아닙니다.

PPS. 예-디자인 패턴 사용-OOP 프로그래밍이 궁극적으로 더 간단 해집니다.

PPPS. OOP 명령 프로그래밍의 동의어로 OOP를 사용했습니다.