# OOP and IF > OOP가 기존의 어떤 개념을 대체하는지 생각해보면 유익할 때가 있다. 레퍼런스는 포인터에서 산술연산을 제거하고, 구조적 프로그래밍은 흐름 제어에서 비구조적 흐름 제어(GOTO 문)를 제거하며, OOP는 상위 계층의 모듈화를 방해하는 `if`, `switch`, `match` 등 선택문을 제거한다. (2005-2007년 사이에 작성) [OOP](https://wiki.g15e.com/pages/Object-oriented%20programming.txt)가 기존의 어떤 개념을 대체하는지 생각해보면 유익할 때가 있다. 레퍼런스는 포인터에서 산술연산을 제거하고, [구조적 프로그래밍](https://wiki.g15e.com/pages/Structured%20programming.txt)은 흐름 제어에서 비구조적 흐름 제어([GOTO 문](https://wiki.g15e.com/pages/GOTO%20statement.txt))를 제거하며, OOP는 상위 계층의 모듈화를 방해하는 `if`, `switch`, `match` 등 선택문을 제거한다. (2005-2007년 사이에 작성) ## 레퍼런스와 포인터 산술연산 의 포인터는 산술 연산을 허용하는 날것의 주소지칭 수단이다. [자바](https://wiki.g15e.com/pages/Java.txt)나 의 레퍼런스(reference)는 포인터에서 산술연산(arithmatic operations)을 제약해서 보안성, 편의성, 효율성 등의 장점을 취한다. ## 구조적 프로그래밍과 GOTO 문 [구조적 프로그래밍](https://wiki.g15e.com/pages/Structured%20programming.txt)은 프로그램의 흐름을 제어하는 방법 중 [GOTO 문](https://wiki.g15e.com/pages/GOTO%20statement.txt)을 제거한다. <다익스트라>의 표현을 빌어 일반화하자면 의미있는 [프로그래머 독립 좌표계](https://wiki.g15e.com/pages/Programmer%20independent%20coordinate%20system.txt)를 훼손하는 장치를 제거하는 게 중요하다. <구조적 프로그램 정리>에 따르면 GOTO가 없더라도 다음 세 가지 수단의 조합으로 흐름 제어를 표현할 수 있다: - 순서(sequence): 쉽게 말해서 재귀적인 함수 호출과 리턴으로 구성된 코드가 위에서 아래로 실행되는 것 - 선택(selection): 쉽게 말해서 `if`, `switch`, `match` - 반복(iteration): 쉽게 말해서 `while`, `do`, `until`, `repeat`, `for` 조건문과 결합된 [GOTO 문](https://wiki.g15e.com/pages/GOTO%20statement.txt)은 날것의 흐름제어 수단인데, 구조적 프로그래밍은 이를 제약함으로써 이해가능성, 모듈화 등의 장점을 취한다. ## OOP와 IF 문 혹자는 OOP가 구조적 프로그래밍을 대체한다고 말하는데 이는 1/3 정도만 맞는 표현이다. OOP는 <서브타입 다형성>을 통해 구조적 프로그래밍의 세 가지 흐름 제어 수단 중 선택, 즉 `if`, `switch`, `match` 등을 대체한다고 생각해볼 수 있다. 조건문이란 애초에 분기 선택(selection) 메커니즘인데 '선택'이란 특정 변수의 값에 따라 이후에 실행할 코드가 달라지도록 하는 걸 말한다. `if` 문에서는 조건절의 `boolean` 값에 따라 선택이 수행되는 것이고, 서브타입 다형성에서는 메시지를 수신하는 인스턴스의 타입에 따라 선택이 수행된다. 다음은 전통적인 방식: ```Java if(mediaType === "monitor") { renderToMonitor(); } else if(mediaType === "printer") { renderToPrinter(); } else { throw new IllegalArgumentException("Unknown media: " + mediaType); } ``` 다음은 서브타입 다형성를 활용한 방식: ```java abstact class Media() { void render() } class Monitor extends Media() { void render() { /* ... */ } } class Printer extends Media() { void render() { /* ... */ } } // ... media.render(); ``` 서브타입 다형성과 이를 이용한 [의존성 역전](https://wiki.g15e.com/pages/Dependency%20inversion.txt)이 OOP를 특징지을 정도로 중요한 관점일 수 있나? 몇몇 이들은 그렇다고 주장한다. > 프로그램이 어떤 언어로 작성되었는지는 중요치 않습니다. 만약 의존성이 역전되어 있다면 이는 객체지향적 설계인 것입니다. (It doesn't matter what language a program is written in. If its dependencies are inverted, it has an OO design.) > > --, 오해의 소지가 있으니 부연하자면, 모든 `if`를 제거해야 객체지향 디자인이라는 주장은 아니다. 마틴 파울러의 설명을 인용하자면 이렇다: > 우리가 조건문에 무조건적으로 반대하는 건 아니다. 이 책(리팩토링)의 초판에서는 "switch 문"이라는 이름의 악취가 있었다. [1990년대](https://wiki.g15e.com/pages/1990s.txt) 후반에는 슬프게도 다형성이 충분히 널리 인식되지 못했기에, 사람들이 `switch` 대신 다형성을 선택하는 게 이롭다고 봤기 때문이다. --[Refactoring: Improving the design of existing code](https://wiki.g15e.com/pages/Refactoring%20-%20Improving%20the%20design%20of%20existing%20code.txt) ## 캡슐화와 정보 은닉 보통 OOP의 세 가지 특징으로 다형성, 캡슐화, 정보 은닉을 꼽는데 이 중 다형성이 특별히 더 중요하다고 볼 수 있을까? 세 가지 모두 중요하지만 <캡슐화>나 <정보 은닉>은 OOP 이전에도 원래 있던 개념들이라는 점에서, 다형성은 상대적으로 눈에 띄는 차별점이다. ## if를 모두 제거해야 진정한 OOP인가? 두 가지를 이야기할 수 있겠다. - 첫째, "진정한 OOP"는 정의하기도 모호하고 별로 추구해야할 가치도 아니다. - 둘째, 모든 `if`가 아니라 상위 계층의 모듈화를 저해하는 `if`를 제거하는 게 중요하다. OOP가 서브타입 다형성을 써서 상위 계층의 모듈화를 저해하는 `if`를 대체한다는 관점은 OOP를 이해하는 여러 유익한 관점 중 하나다.