객체 지향 프로그래밍이란 스스로 책임을 수행하는 자율적인 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
OOP의 특징
추상화
객체들에서 공통의 속성이나 기능을 묶어 상위 클래스를 생성하는 것
동작의 공통적인 특징을 찾아낸 뒤 간단하게 표현하는 것
상속
상위 객체의 필드와 메소드를 하위 객체에게 물려줘 하위 객체가 상위 객체의 기능을 사용할 수 있도록 하는 것.
다형성
어떤 하나의 객체가 여러 개의 형태를 갖는 것 오버로딩이나 오버라이딩을 통해 다형성을 구현할 수 있다.
overloading: 같은 이름의 함수를 매개변수의 개수나 타입에 따라서 다르게 사용하는 것.
overriding: 부모 클래스의 메소드를 자식 클래스에서 똑같은 이름, 같은 반환 값, 같은 인자로 재 정의 하는 것.
캡슐화
비슷한 역할을 하는 필드와 메서드들을 하나로 묶고, 구현 내용을 외부에 감춰 외부 객체에서 객체 내부의 구조를 알지 못하고 객체가 노출한 public 필드와 메소드에만 접근 가능하게 하는 것.
캡슐화를 위한 두 개의 규칙
Tell Don't ask
데이터를 물어보지 않고, 기능을 실행해 달라고 말하라는 규칙.
필드를 private로 클래스 내부에 숨기고, 메소드를 통해서만 필드에 접근가능
데미테르 법칙
메서드에서 생성한 객체의 메서드만 호출
파라미터로 받은 객체의 메서드만 호출
필드로 참조하는 객체의 메서드만 호출
객체 지향적 설계 원칙(SOLID원칙)
SRP(Single Responsibility Principle): 단일 책임 원칙
클래스는 단 하나의 actor(시스템이 동일한 방식으로 변경되기를 원하는 사용자 집단)에 대한 책임을 가져야 한다
클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
SRP를 안 지킬 경우, 서로 다른 액터가 의존하는 코드들이 너무 가까이 있기 때문에 잦은 컨플릭트와 다른 도메인 서비스에서의 예기치 못한 사이드 이펙트가 발생할 수 있다.
해결 방법
어떤 한 데이터가 여러 이유로 사용되면, 데이터와 메서드를 분리해서,
somethingData
같은 클래스를 만든 뒤 서브 클래스들이 상위 클래스의 필드를 공유하고 서브 클래스들은 서로의 존재를 모르게 변경한다.위 방법대로 하면 개발자가 서브 클래스들을 다 인스턴스화 하고 추적해야 하는 문제가 발생할 수 있다. 그런 경우 퍼사드 패턴을 이용해, 퍼사드 객체에서 서브 클래스들의 인스턴스를 생성하고 고수준의 인터페이스를 제공해줘서 인스턴스들을 캡슐화 할 수 있다.
OCP(Open-Closed Principle): 개방-폐쇄 원칙
소프트웨어 개체는 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
다시 말해 소프트웨어 개체의 행위는 확장할 수 있어야 하지만, 이때 기존 개체를 변경해서는 안 된다.
OCP의 목표는 시스템을 확장하기 쉬운 동시에 변경으로 인해 시스템이 너무 많은 영향을 받지 않도록 하는 데 있다.
LSP(Liskov Substitution Principle): 리스코프 치환 원칙
상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
ISP(Interface Segregation Principle): 인터페이스 분리 원칙
클라이언트(기능을 사용하는 클래스)는 사용하지 않는 인터페이스에 의존하면 안된다.
인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리되어야 한다.
클래스에 자신이 사용하지 않는 인터페이스는 구현되지 말아야한다.
DIP(Dependency Inversion Principle): 의존 역전 원칙
고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.
저수준 모듈은 고수준 모듈이 정의한 추상 타입에 의존해야 한다.
Last updated