JavaRush /Java Blog /Random-KO /객체 지향 프로그래밍(기사 번역)
Exidnus
레벨 38
Санкт-Петербург

객체 지향 프로그래밍(기사 번역)

Random-KO 그룹에 게시되었습니다
번역자: 불행하게도 저는 영어로 꽤 많이 읽었지만 영어로 번역한 경험이 별로 없습니다. 그러나 읽는 것과 번역하는 것은 서로 다른 일이라는 것이 밝혀졌습니다. 또한 불행하게도 나는 프로그래밍 경험이 많지 않습니다. (나는 최근에 Spring MVC와 Hibernate에서 간단한 웹 애플리케이션을 만들었습니다.) 따라서 번역은 가능한 것보다 훨씬 더 나빴습니다. 기사에 제공된 코드 예제는 Java의 명명 규칙을 준수하지 않기 때문에 자유롭게 약간 수정했습니다. 아마도 일부 패턴의 이름을 번역할 가치가 없을 수도 있지만(이러한 번역은 많은 이해를 제공하지 않음) 이것이 덜 악하다고 생각했습니다. '높은 응집력'을 번역한 '높은 응집력'에 대해서는 별도로 언급할 가치가 있습니다. 동의합니다. 최고의 번역은 아닙니다. 그러나 "강한 연결성"은 "높은 결합"(또 다른 중요한 개념)이며 여기서 "일관성"은 적합하지 않을 것입니다. 나는 비판에 개방적이며 어떤 형태로든 기사에 대한 의견을 감사히 받아들입니다. 객체 지향 프로그래밍은 프로그램이 실제 객체에 해당하는 구성 요소로 구성되는 프로그래밍 스타일입니다. 모든 실제 객체에는 몇 가지 속성(시간이 지남에 따라 변경되거나 변경되지 않을 수 있음)과 동작(변경될 수도 있고 변경되지 않을 수도 있음)이 있습니다. 다른 사람에 따라 변경).조건). 예를 들어, 연필은 다음과 같은 속성을 가진 실제 개체입니다.
  • 빨간색입니다(시간이 지나도 변하지 않음).
  • 이제 길이는 10센티미터입니다(연필을 깎으면 길이가 바뀔 수 있습니다).
그리고 다음과 같은 동작을 합니다:
  • 올바르게 사용하면 흔적이 남습니다.
  • 압력에 따라(외부 요인에 따라) 흔적이 다를 수 있습니다.
  • 날카롭게 하면 길이가 짧아집니다(영구적 거동).
이 예에서와 같이 실제 객체는 많은 속성을 가질 수 있지만 프로그램을 작성할 때는 필요한 속성만 고려합니다. 객체 지향 프로그래밍에는 장점이 있습니다. 예를 들어, 예상되는 방식으로 실제 개체와 프로그램 간의 연결을 더 쉽게 설정할 수 있습니다. 이는 애플리케이션이 성장하고 많은 개체가 서로 상호 작용할 때 정말 도움이 됩니다. 이는 객관적인 세계 내에서 책임을 분산하는 데 도움이 되므로 애플리케이션을 통해 사고하는 데 집중할 수 있습니다. OOP (객체 지향 프로그래밍) 와 관련된 또 다른 중요한 기능은 객체 분류입니다. 세상(현실/가상)은 사물로 가득 차 있기 때문에 개별적으로 제어하기가 어렵습니다. 검은색 연필과 같이 다양한 개체와 해당 속성을 연결하는 데 도움이 되는 이러한 개체를 분류하는 방법이 필요합니다. 이전 예제에서 사용했다면 구별이 불가능(동일?)하겠지만, 다른 객체입니다. 하지만 둘 다 연필이기 때문에 같은 클래스인 "연필"에 속합니다. 연필과 매우 유사한 펜은 다른 클래스에 속합니다. 그러나 펜과 연필은 모두 '필기 도구'입니다. 객체 지향 프로그래밍에는 다음과 같은 원칙이 있습니다.
추출
추상화는 사건보다는 아이디어와의 상호작용 품질 , 즉 표현적 품질로부터의 자유 로 정의됩니다 . 이를 통해 프로그래머는 어떻게 프로그래밍할지 보다는 무엇 프로그래밍할지 에 집중할 수 있습니다 . 추상화는 기능을 제공하는 계약으로 생각할 수 있습니다. 이 개념을 사용할 때 구현 세부 사항이 숨겨질 수 있습니다. 예를 들어, 쓰기를 수행하는 클래스가 필요한 경우 해당 클래스에 "write" 메서드가 있는지 확인해야 합니다. 우리는 무엇을 했나요? 우리는 추상적인 상위 수준 클래스를 설계했습니다. 즉, 필요한 기능이 무엇인지 알고 있지만 이를 구현하는 방법은 이 클래스의 범위를 벗어납니다. 이는 다음과 같은 많은 이점을 제공합니다. abstract class writer { write (); }
  • 우리는 외부 주체에게 필요한 최소한의 정보를 공개함으로써 프로그램을 통해 사고에 집중할 수 있게 하고(이로 인해 집중적인 사고가 가능해짐) 혼란을 피하고 의도하지 않은 약속을 하는 것을 피할 수 있습니다.
  • 구현 세부 사항이 공개되면 불가능할 향후 개선의 여지를 남겨둡니다.
계승
일반적인 영어로 "상속"은 "획득하고 전달하다"를 의미합니다. 이 단어는 우리 문화에 아주 오랫동안 존재해 왔습니다. 조상들은 열심히 일하여 땅을 얻어 자식들에게 물려주었고, 자연도 상속을 선호합니다. 키, 피부/눈/머리 색깔 등과 같은 모든 신체 속성입니다. 우리는 부모로부터 물려받은 유전자에 의존합니다. 상속은 바퀴를 재발명하는 것을 방지하고 진행 속도를 높입니다. OOP에서도 마찬가지입니다. 몇 가지 기본 속성/동작을 사용하여 상위 클래스를 만듭니다. 이 상위 클래스에서 상속되는 모든 클래스는 해당 상위 클래스와 동일한 속성/동작을 포함합니다. 그러나 상속된 클래스는 더 많은 속성/동작을 얻거나 동작 구현을 변경할 수 있습니다. class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; } 위의 예에서 상위 클래스(WritingInstrument)에는 "color" 속성과 "write" 동작이 있습니다. 하위 클래스(핸들)가 선언되면 "color" 속성과 "write" 동작을 다시 선언할 필요가 없습니다. 상속으로 인해 "handle" 클래스에 존재합니다. 그러나 하위 클래스는 자체 추가 속성/동작을 선언할 수 있습니다. 이것을 실제로 어떻게 사용할 수 있습니까? 우리 개발자들은 매우 게으릅니다. 우리는 무언가를 계속해서 인쇄하고 싶지 않습니다. 다음 고려 사항으로 인해 동일한 코드의 복사본이 여러 개 존재하는 것은 권장되지 않습니다.
  • 코드 복사본이 적을수록 유지 관리가 더 쉬워집니다.
  • 코드 사본이 많지 않으면 한 곳의 변경 사항이 모든 곳에서 표시됩니다.
  • 코드가 적을수록 오류도 줄어듭니다.
  • 하나의 코드가 여러 곳에서 사용되면 일반화가 이루어집니다.
  • 우리는 코드 작성에 중점을 둡니다.
  • 우리는 테스트에 집중합니다.
Java의 상속은 "확장" 및 "구현"이라는 키워드를 사용하여 수행됩니다. class WritingInstrument { } class Pen extends WritingInstrument { }
다형성
"다형성"이라는 단어는 "폴리" 라는 두 단어에서 유래되었습니다 . "다수" / "하나 이상" "모프" , 즉 "형태" 문자 그대로 "다형성"이라는 단어는 조건에 따라 개체가 다른 방식으로 동작하는 능력을 나타냅니다. 프로그래밍에서 다형성은 여러 위치에서 구현될 수 있습니다.
  • 클래스
  • 행동 양식
  • 운영자
위의 모든 내용은 조건, 즉 사용되는 상황에 따라 다르게 작동할 수 있습니다. 이는 클라이언트(라이브러리를 사용하는 프로그래머)가 많은 세부 사항을 알 필요가 없고 컨텍스트에서 필요한 정보를 선택하여 원하는 기능이 구현되기 때문에 유용합니다. Class WritingObject { wrire() { // пишем, используя стандартные (по дефолту) цвета } } class Pencil extends WritingObject { write() { // пишем, используя серый цвет, написанный текст можно стереть } } class Pen extends WritingObject { write() { // пишем, используя голубой цвет, написанный текст нельзя стереть } } class Main { main() { WritingObject wr = new WritingObject(); wr.write(); // первый вызов WritingObject wr = new Pen(); wr.write(); // второй вызов WritingObject wr2 = new Pencil(); wr2.write(); // третий вызов } } 위의 예에는 하위 클래스인 pen 및 pen에 의해 확장/재정의되는 WritingObject의 기본 구현이 있습니다. write() 메서드는 Main 클래스에서 세 번 호출됩니다. 메소드가 호출되는 객체에 따라 다른 구현이 호출될 때마다. 이 경우 write() 메서드는 다형성이므로 다양한 유형의 동작을 갖습니다.
캡슐화
캡슐화는 관련 데이터/기능을 하나의 단위로 수집하는 것으로 정의됩니다. 이는 데이터 액세스/수정을 용이하게 하는 데 도움이 됩니다. 예를 들어 특정 사용자가 가지고 있는 모든 속성을 인쇄해야 하는 경우 다음과 같은 옵션이 있습니다. printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….) 모든 속성을 가져와 차례로 인쇄하는 메서드를 만들었습니다. 목록의 요소 수가 증가하면 더 이상 올바른 필드를 식별할 수 없으며 하나의 필드를 추가/제거하면 메서드 시그니처가 변경됩니다. 따라서 최근 추가된 필드가 필요하지 않더라도 이 방법을 사용하는 모든 사용자를 교체해야 합니다. 코드를 더 읽기 쉽게 만들고 향후 수정을 더 쉽게 만들기 위해 속성을 클래스에 캡슐화하고 이를 집합 개체로 변환합니다. class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {} 개체는 변수 및 관련 메서드의 소프트웨어 번들입니다. 프로그램 개체를 사용하여 실제 개체를 표현할 수 있습니다. 애니메이션 프로그램에 나오는 실제 개를 상상하거나 운동용 자전거 내부의 소프트웨어 개체로 실제 자전거를 상상할 수 있습니다. OOP에서 클래스는 객체를 생성하고 객체에 초기 상태(변수)를 제공하며 동작(함수, 메서드)을 구현하기 위한 확장 가능한 템플릿(프로그램-코드-템플릿)입니다. SOLID라는 약어는 2000년대 초 Robert C. Martin이 명명한 "처음 5가지 원칙"을 의미하는 Michael Feather가 만든 것입니다. 원칙의 목표는 함께 구현될 때 프로그래머가 유지 관리 및 확장이 쉬운 시스템을 만들 가능성을 높이는 것입니다. SOLID 원칙은 리팩토링을 통해 "썩은" 코드를 제거하는 데 필요한 프로그램 개발 지침이며, 그 결과 코드는 쉽게 읽을 수 있고 확장 가능해야 합니다. 이는 민첩하고 적응 가능한 프로그래밍 전략의 일부입니다.
단일 책임 원칙
OOP에서 단일 책임 원칙은 각 클래스가 프로그램에서 제공하는 기능의 한 부분을 담당해야 하며 해당 책임은 해당 클래스에 의해 완전히 캡슐화되어야 함을 나타냅니다. 모든 기능은 이 책임과 밀접하게 관련되어 있어야 합니다.
개방형/폐쇄형 원칙
OOP에서 개방/폐쇄 원칙은 "소프트웨어 엔터티(클래스, 모듈, 메서드 등)는 확장에는 개방되어야 하지만 변경에는 폐쇄되어야 한다"고 명시합니다. 즉, 엔터티는 소스 코드를 변경하지 않고도 해당 동작을 확장할 수 있어야 합니다.
Liskov 대체 원칙
대체성은 OOP의 원칙입니다. 컴퓨터 프로그램의 S가 T의 하위 유형인 경우 T 유형의 개체는 변경 없이 S 유형의 개체로 대체될 수 있어야 합니다(즉, S 유형의 개체는 T 유형의 개체로 대체될 수 있음). 필수 속성 프로그램(정확성, 작업 완료 등).
인터페이스 분리 원칙
인터페이스 분리의 원칙은 클라이언트 프로그래머가 사용하지 않는 방법에 의존하도록 강요해서는 안 된다는 것입니다. 이 원칙에 따르면, 클라이언트 프로그래머가 자신에게 흥미로운 방법만 알 수 있도록 대규모 인터페이스를 더 작고 더 구체적인 인터페이스로 나누는 것이 필요합니다. 인터페이스 분리 원칙의 목적은 시스템을 분리된 상태로 유지하여 리팩터링, 변경 및 재배포를 더 쉽게 만드는 것입니다.
종속성 반전 원리
OOP에서 종속성 역전의 원칙은 프로그램 모듈 간의 특정 형태의 연결 끊김을 의미합니다. 이 원칙에 따라 애플리케이션 아키텍처를 구성하는 상위 모듈(정책 설정)에서 종속 하위 모듈로 설정된 표준 종속 관계가 반전(역전)되어 수정된 상위 모듈이 구현 세부 사항과 독립됩니다. 저수준 모듈. 이 원칙은 다음과 같이 명시합니다.
  • 높은 수준의 모듈은 낮은 수준의 모듈에 의존해서는 안 됩니다. 두 가지 유형의 모듈 모두 추상화에 의존해야 합니다.
  • 추상화는 구현 세부 사항에 의존해서는 안 됩니다. 세부 사항은 추상화에 따라 달라져야 합니다.
이 원칙은 높은 수준과 낮은 수준의 개체가 동일한 추상화에 의존해야 한다고 주장함으로써 사람들이 개체 지향 디자인에 대해 생각할 수 있는 방식을 뒤집습니다.

GRASP 원칙

GRASP(일반 책임 할당 소프트웨어 패턴)는 객체 지향 디자인에서 클래스와 개체에 책임을 할당하기 위한 지침을 제공합니다.
제어 장치
컨트롤러 패턴은 전체 시스템 또는 사용 사례 시나리오를 나타내는 비 GUI 클래스에 시스템 이벤트와의 상호 작용 책임을 할당합니다. 제어 장치:
  • 이는 사용자와 직접 상호작용하지 않으며 시스템 이벤트를 수신하고 응답하는 역할을 담당하는 개체입니다.
  • 하나(또는 여러 상호 관련된) 사용 사례의 모든 시스템 이벤트를 처리하는 데 사용해야 합니다.
  • 시스템 작동을 제어하는 ​​GUI 뒤의 첫 번째 개체입니다.
  • 그는 스스로 작업을 수행할 필요가 없으며 그의 임무는 이벤트의 흐름을 제어하는 ​​것입니다.
창조자
작성자 클래스의 임무는 후속 사용을 위해 개체를 만들고 시작하는 것입니다. 초기화 매개변수와 생성될 객체를 알고 있습니다. 때때로 생성자 클래스는 객체를 적극적으로 생성하여 캐시에 저장하고 필요할 때 하나의 인스턴스를 제공합니다.
높은 응집력
높은 응집력은 하나의 명확한 작업을 수행하는 것을 목표로 하고 쉽게 제어하고 이해할 수 있는 상태로 개체를 보존하는 것이 목적인 평가 패턴입니다. High Coupling은 일반적으로 Low Coupling을 지원하는 데 사용됩니다. 높은 일관성이란 특정 요소의 책임이 명확하게 정의되어 있음(강하게 관련되어 있고 고도로 집중되어 있음)을 의미합니다. 프로그램을 클래스와 하위 시스템으로 나누는 것은 시스템 속성의 응집력을 높이는 작업의 예입니다. 반면에 느슨한 결합은 요소에 관련되지 않은 작업이 너무 많은 상황입니다. 느슨하게 결합된 요소는 이해하기 어렵고 재사용이 가능하며 유지 관리 및 변경이 어려운 경향이 있습니다.
우회
Roundabout 패턴은 두 요소 간의 상호 작용에 대한 책임을 중간 개체에 할당하여 두 요소 간의 느슨한 결합(및 재사용성)을 유지합니다. MVC(Model-View-Controller) 패턴에서 데이터(모델)와 해당 디스플레이(뷰) 사이를 중재하는 컨트롤러를 도입하는 것이 그 예입니다.
정보전문가
정보 전문가(전문가 또는 전문가 원칙이라고도 함)는 누구에게 책임을 위임할지 결정하는 데 사용되는 원칙입니다. 책임에는 메서드, 계산 필드 등이 포함됩니다. 책임을 할당할 때 이 원칙을 사용할 때 주요 접근 방식은 책임 분석, 책임 이행에 필요한 정보 식별, 최종적으로 이 정보의 위치 설정 등 일련의 작업입니다. 정보 전문가 원칙을 사용하면 이를 실행할 정보가 가장 많은 클래스에 책임이 할당됩니다.
낮은 결합
느슨한 결합은 책임 할당 방법을 지정하는 평가 패턴입니다. 클래스 간의 느슨한 결합, 하나를 변경하면 다른 클래스에 최소한의 영향을 미치고 재사용성을 최대화해야 합니다.
다형성
다형성에 따르면 유형에 따른 동작의 변화는 이러한 변화가 발생하는 유형에 할당됩니다. 이는 다형성 연산을 사용하여 달성됩니다.
보호된 변형
보호된 변경 패턴은 인터페이스의 불안정성에 초점을 맞추고 다형성을 사용하여 해당 인터페이스의 다양한 구현을 생성함으로써 다른 요소(객체, 시스템, 하위 시스템)가 변경되지 않도록 요소를 보호합니다.
순수 제작
순수 구성에는 문제 영역의 개념을 나타내지 않는 클래스가 포함되며, 특히 느슨한 결합, 높은 응집력 및 최대 재사용 가능성을 달성하도록 설계되었습니다(정보 전문가 패턴에서 제공하는 솔루션은 이를 달성하지 못합니다). 이러한 클래스를 일반적으로 도메인 중심 설계에서는 "서비스"라고 합니다.

비판

Potok 등의 연구에서는 OOP와 절차적 접근 방식 사이에 큰 차이가 없음을 보여주었습니다.
OOP를 다른 기술, 특히 관계형 기술과 비판적으로 비교하는 것은 엄격하고 널리 받아들여지는 OOP 정의가 부족하기 때문에 어렵습니다(Christopher J. Date).
다른 언어(LISP 방언, 기능적 언어 등)에 비해 OOP 언어는 고유한 장점이 없으며 불필요한 복잡성을 부과합니다. (로렌스 크루브너)
나는 객체 지향 프로그래밍이 기술적으로 허술하다고 생각합니다. 단일 유형 내에서 다양한 인터페이스 측면에서 세계를 여러 부분으로 분해하려고 합니다. 실제 문제를 처리하려면 다양한 유형으로 확장되는 인터페이스 제품군인 다중 정렬 대수가 필요합니다. 나는 객체 지향 프로그래밍이 철학적으로 건강하지 않다고 생각합니다. 모든 것이 객체라고 말합니다. 이것이 사실이라 할지라도 별로 흥미롭지 않습니다. 모든 것이 대상이라고 말하는 것은 전혀 아무 말도 하지 않는 것입니다. (알렉산더 스테파노프)
대기업 사이에서 OOP의 인기는 "대규모(그리고 자주 변화하는) 평범한 프로그래머 그룹"에 기인합니다. OOP가 부과하는 규율은 프로그래머가 "너무 많은 해를 끼치는" 행위를 방지합니다. (폴 그레이엄)
객체 지향 프로그래밍에서는 명사를 최우선으로 생각합니다. 왜 그렇게 극단적인 조치를 취하고 연설의 한 부분을 받침대에 올려 놓습니까? 한 개념이 다른 개념보다 우선하는 이유는 무엇입니까? OOP가 갑자기 동사를 우리의 사고에 덜 중요하게 만드는 것은 불가능합니다. 이상하게 왜곡된 관점이다. (스티브 예게)
Clojure의 창시자인 Rick Hickey는 객체 시스템을 현실 세계의 극도로 단순화된 모델로 설명했습니다. 그는 OOP가 시간을 올바르게 모델링할 수 없다는 점을 강조했는데, 이는 프로그램에서 멀티스레딩이 일반화될 때 큰 문제를 야기합니다. Unix 프로그래머이자 오픈 소스 소프트웨어 옹호자인 Eric S. Raymond는 OOP가 "하나의 솔루션"이라는 주장을 비판해 왔으며 OOP가 투명성을 방해하는 다중 계층 프로그램을 장려한다고 썼습니다. 이에 반대되는 접근 방식으로 Raymond는 Unix와 C의 예를 들었습니다.

연결

작성자: Margaret Rouse @ WhatIs.com Wikipedia! ( 러시아어 버전 ) 상속은 다형성입니다 SOLID (객체 지향 디자인) ( 러시아어 버전 ) OOPS에 대한 단일 책임 원칙 논쟁 ( 러시아어 버전 ) OOPS 란 무엇입니까 (과장 없음) 번역: Varygin D.V.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION