하나의 포스트로 내용을 정리하기에는 너무나 방대하지만 면접에서 사용할 수 있을 정도로만 정리해 보았다.
객체 지향 프로그래밍 이전의 프로그래밍 패러다임을 살펴보면 컴퓨터를 중심으로 프로그래밍 하였다. 컴퓨터의 눈높이에서 컴퓨터의 방식대로 프로그래밍하는 것이다. 그러나 객체 지향 프로그래밍은 인간을 중심으로 프로그래밍하는 패러다임이다. 현실 세계를 프로그래밍으로 옮겨와 프로그래밍을 하는 것이다. 현실 세계의 사물들을 객체로 보고, 그 객체로부터 개발하고자 하는 어플리케이션에 필요한 특징들을 뽑아와 프로그래밍하게 되며 이 과정을 추상화라고 한다.
오퍼레이션의 사용법 세가지를 시그니처라고 부른다. 오퍼레이션의 사용법에는 기능 식별 이름
, 파라미터 및 파라미터 타입
, 기능 실행 결과 값 및 타입
이 있다.
인터페이스는 객체가 제공하는 모든 오퍼레이션 집합을 의미한다. 이는 객체를 사용하기 위한 명세를 의미한다고 볼 수 있다.
오퍼레이션의 실행을 요청하는 것을 메세지 보낸다고 표현한다. 자바에서 메서드를 호출하는 것이 메세지를 보내는 것에 해당한다.
객체가 자신이 제공하는 기능으로 정의된다는 것은 객체마다 자신만이 제공할 수 있는 기능에 대한 책임이 있는 것이다. 객체는 자신의 책임이 작을수록 좋다. 이 말은 객체가 제공하는 기능의 개수가 적은 것이 좋다는 것을 의미한다. 하나의 객체에 많은 기능이 포함되면 그 기능과 관련된 데이터들도 한 객체에 모두 포함되게 되고 이는 객체에 정의된 많은 오퍼레이션들이 데이터를 공유하는 방식으로 프로그래밍된다. 이는 절차 지향 방식과 유사하기 때문에 객체 지향에서의 책임은 작을수록 좋다.
클래스는 단 하나의 책임을 가져야하며 클래스를 변경하는 이유는 단 하나의 이유여야 한다.
확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다. OCP는 객체를 추상화함으로써 확장에는 열려있고, 변경에는 닫혀있는 유연한 구조를 만들어야 한다는 원칙이다.
확장에 열린 것은 모듈의 확장성을 보장하는 것을 의미한다. 새로운 변경 사항이 발생했을 때 유연하게 코드를 추가 또는 수정할 수 있기 때문이다.
객체를 직접적으로 수정하는 것은 제한해야 한다. 기능이 추가되거나 수정될 때 객체를 직접적으로 수정해야 한다면 새로운 변경 사항에 대해 유연하게 대응할 수 없는 어플리케이션이다. 이는 유지보수의 비용증가의 원인이 될 수 있고 객체 지향적인 설계라고 볼 수도 없다.
따라서 객체를 직접 수정하지 않고도 변경 사항을 적용할 수 있도록 설계해야 한다. 이를 변경에 닫혀있다고 표현한다.
상위 타입의 객체를 하위 타입의 객체로 치환해도 사위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
인테페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다. 이 말은 범용 인터페이스 하나보다 특정 클라이언트를 위한 여러 개의 인터페이스 분리를 더 지향한다는 것을 의미한다.
결국은 확장성이 커지는 셈이다.
고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다. 이는 프로그래머가 구체화가 아닌 추상화에 의존해야 한다는 것을 의미한다. 구현 클래스(구현체)가 아니라 인터페이스(역할)에 의존하라는 말로도 해석이 가능하다.