OOP는 명사의 중요성을 과도하게 강조하여 행동 / 동사를 덜 중요한 위치에 두나요? [닫기]
Steve yegge는 2006 년에 " 명사의 왕국에서 실행 "이라는 기사를 썼습니다. 14 년이 지난 지금도 그가 타당한 요점을 발견했습니다. 예를 들어, "행동은 삶에 활기를 불어 넣는 것입니다 ... (그러나) 객체 지향 프로그래밍은 명사를 최우선으로 생각합니다 ... 명사는 사물이며 사물은 Java 왕국의 모든 행동을 뛰어 넘는 가치가 있습니다".
그가 사용한 예는 여전히 저에게 공감합니다. 대부분의 경우 작업을 수행하기 위해 코드 조각을 작성할 때 일반적으로 일련의 작업으로 구성됩니다. 요점을 설명하기 위해 쓰레기를 버리는 그의 예를 사용하여,
/*To take out the the garbage*/
get the garbage bag from under the sink
carry it out to the garage
dump it in the garbage can
wash my hands
get back to my couch
...
여기에 필요한 것은 일련의 행동이지, 같은 명사의 연속이 아닙니다.
A GarbageDisposalStrategy nouns,
A GarbageDisposalDestinationLocator nouns for finding my way to the garage,
A PostGarbageActionCallback nouns for putting me back on my couch.
...
run (), execute () 또는 dothis ()와 같은 공용 메서드를 사용하여 모든 종류의 관리자 클래스에서 너무 많은 코드를 보았습니다.
제 요점을 더 설명하기 위해 좀 더 현실적인 예를 들어 보겠습니다. 사람들은 항상 올바른 문제에 적합한 패러다임을 선택한다고 말합니다. 웹 개발을 예로 들어 보겠습니다. 웹 개발에는 Java뿐만 아니라 많은 OOP와 프레임 워크가 있습니다. 하지만 웹 개발을 위해 nodejs (익스프레스)를 사용하기 때문에 OOP를 절대 사용하지 않으며 절대 놓치지 않습니다. Express의 미들웨어는 기능 체인 일뿐입니다.
따라서 OOP와 절차 설계 모두 웹 개발에 적합합니다. 그러나 express를 사용하면 훨씬 더 쉽게 느껴집니다. 프레임 워크와 프레임 워크의 모든 디자인 및 트위스트를 배우는 대신 "실제"코드를 개발하는 데 더 많은 시간을 할애합니다.
웹 개발을위한 "올바른"패러다임은 무엇입니까?
특히 Java (웹 개발 및 일반적)에서 OOP의 단점은 무엇입니까? OOP는 명사의 중요성을 과장하여 행동 / 동사를 덜 중요한 위치에 두 나요?
또한 내 질문은 함수형 프로그래밍을 논의 / 홍보하거나 언어 전쟁을 시작하는 것이 아님을 강조해야합니다. 나는 내 질문이 의견에 근거하거나 너무 광범위하게 보일 수 있다는 것을 충분히 알고 있습니다. 그러나 14 년이 지난 후에도 문제가 여전히 여기에 있다는 사실은 제가이 질문을하게 만듭니다.
---- 업데이트 ----
한 번 더 투표하면 내 게시물이 삭제됩니다. 그러나 미래의 독자 여러분, 삭제에 투표하지 마십시오. 폐쇄되었습니다. 왜 삭제합니까? 나는 그것이 유효한 우려를 제기한다고 생각하는데, 왜 그것을 삭제합니까?
내 질문이 마감되었지만 (예상대로) stackoverflow (질문 제목을 변경하기 전)에도 동일한 질문이 있었음을 지적하고 싶습니다. https://stackoverflow.com/questions/2853316/disadvantage-of-oop
거기에 좋은 답변이 있으니 관심이 있으시면 한 번보세요. 내가 동의하는 대답은 (내 코드 중 많은 부분이 변형 처리이기 때문일 수 있습니다)
OOP는 대규모, 다중 개발자, 다중 모듈 프로젝트에서 가장 잘 작동합니다. 스크립팅 또는 변형 처리와 같은 "소규모 개발"의 경우 반드시 가치를 추가하지 않고도 상당한 오버 헤드가 필요할 수 있습니다.
...
변형 처리는 프로그래밍의 기능적 스타일에 상당히 적합합니다.
추신 : Steve yegge의 기사가 횡설수설이라고 생각한다면 Joe Armstrong (erlang의 아버지) 기사 Why OO Sucks , 훨씬 더 짧고 요점에 바로 똑바로 있지만 기본적으로 " 데이터 구조 및 함수는해서는 안됩니다. 함께 묶여. "
답변
OOP의 문제점 중 하나는 OOP는 것이 아닙니다 이다 , 그러나이 어떻게되어 가르쳤다 .
"Object-Oriented Programming"이라는 용어를 만든 Alan Kay는 메시징 이 OOP에서 가장 중요한 것임을 여러 번 분명히 밝혔습니다 . 그는 심지어 그것을 Object- Oriented 라고 불렀다는 것을 후회 하고 대신 Message- Oriented라고 불렀어야한다고 말했습니다 .
따라서 OOP의 첫날부터 초점은 사물이 아닌 상호 작용 에 있었습니다.
그러나 객체 지향 분석을위한 첫 번째 기법은 "사용 사례의 모든 주제, 동사 및 객체에 밑줄을 긋는 것입니다. 주제는 클래스, 동사 방법 및 객체 필드가됩니다."
이 방법론 이 객체에 초점을 맞추지 않고 클래스 에 초점을 맞추는 방법에 유의하십시오 .
그러나이 방법론이 좋은 방법론이라고 가정 하더라도 사용 사례를 공식화하는 방법에 따라 여전히 매우 다른 디자인으로 끝날 수 있습니다.
제가 가장 좋아하는 예 중 하나는 은행입니다. 은 BankAccount
하나 OOP에서 가장 널리 사용되는 입문 예입니다. 그리고 "모두가"가 무엇인지 압니다 BankAccount
. 맞죠?
class BankAccount {
private Money balance;
void deposit(Money amount) {
balance += amount;
}
bool withdraw(Money amount) {
if (balance < amount) { return false; }
balance -= amount;
return true;
}
}
쉬워요. 이제 transfer
메소드를 추가하십시오 . 오, 잠깐, 어떤 물건에 속합니까? 합니까 A
이전 에 B
또는 않는 B
전송 에서 A
? 그리고 동시성은 어떻습니까?
class BankAccount {
Money balance;
void deposit(Money amount) {
balance += amount;
}
bool withdraw(Money amount) {
if (balance < amount) { return false; }
balance -= amount;
return true;
}
bool transfer(Money amount, BankAccount target) {
if (balance < amount) { return false; }
withdraw(amount);
target.deposit(amount);
return true;
}
}
"균형"이 데이터이고 "이전"이 행동이라는 것을 "모두 알고 있습니다". 권리? 권리?
글쎄, 그것이 작동하는 방식이 아니라는 것이 밝혀졌습니다. 사실, 그것은 은행 송금이 처음 발명되었을 때까지 그렇게 작동 하지 않았습니다 .
이체 할 때 발생하는 일은 점원이 거래 전표를 작성 하고 영업일이 끝나면 계정의 모든 거래 전표가 집계되어 새로운 잔액이 생성됩니다. 그런 다음 거래 전표가 수신 은행으로 전송되어 동일한 일이 발생합니다.
따라서 "실제 세계"(모든 OOP 튜토리얼에서 우리가 모델링해야한다고 가르친다)에서 트랜잭션은 실제로 데이터 이고 잔액은 실제로 작업입니다 !
record Transaction(BankAccount source, BankAccount target, Money amount)
class BankAccount {
Money balance() {
// find all transaction slips which have `this` as either source or target
// add all the amounts which have `this` as target
// subtract all the amounts which have `this` as source
return result;
}
void deposit(Money amount) {
TransactionLog.append(new Transaction(CASH, this, amount));
}
void withdraw(Money amount) {
TransactionLog.append(new Transaction(this, CASH, amount));
}
}
모든 동시성 문제는 사라집니다. BankAccount
불변성, Transaction
불변성, "거의 불변성"추가 전용 만 필요합니다 TransactionLog
. 또한 전체 감사 추적을 무료로받을 수 있으며 부분적인 데이터 손실을 복구 할 수 있습니다.
말 택배를 통해 지점과 은행 사이에서 거래 전표를 이동하는 것이 위험하고 며칠이 걸렸을 때부터 이것이 은행이 수행 된 방식이라고 생각하면 실제로 놀라운 일이 아닙니다. 이것은 분산 전자 뱅킹 시스템 과 똑같은 문제와 속성 을 가지고 있습니다.
따라서 보시다시피 문제에 다르게 접근하는 것만으로 똑같은 문제에 대한 명사와 동사의 역할을 뒤집을 수 있습니다.
또한 문제와 컨텍스트의 복잡성으로 인해 여러 독립적 인 동시 행위자, 즉 은행의 두 지점 이상 이 필요하다는 점에 유의하십시오 . 이것이 OOP가 되어야 하는 것입니다. 여러 독립된 행위자가 메시지를 교환하면서 협력하면서 자신의 작업을 나머지 세계로부터 숨기는 것입니다.
사람들이 문제에 대해 생각할 때 "일련의 행동"에 대해 생각하는 것은 정상입니다. 쉽고, 모든 것이 당신의 완전한 통제하에 있습니다. 그것은 잘못된 것이 아닙니다. 그것은 단지 생각의 방법입니다.
OO는 완전히 다른 생각을 요구합니다. 명령 및 제어 대신 업무를 동료 간의 협력 으로 생각하는 것이 좋습니다 . 그것은 "사물"에 관한 것이 아니라 생명체 에 관한 것입니다. 다른 존재 (즉, 객체)에게 작업을 위임 하기 위해 자신의 통제권을 포기합니다 .
귀하의 질문에 답하기 위해 : 링크 된 기사는 물론 BS이거나 오히려 짚맨입니다. 물론 OO를 아주 나쁘게하고 있고 모든 것을 지나치게 복잡하게 만든다면 꽤 나빠 보일 것입니다. 그것이 일부 프레임 워크 나 라이브러리에 적용 되더라도 여기서는 OO가 아니라 사람들의 잘못된 해석 일뿐입니다.