[객체지향 프로그래밍]

서승·2025년 6월 29일

기술 지식

목록 보기
8/12

객체지향

객체지향 프로그래밍이란 ?

프로그래밍에서 필요한 데이터를 추상화 시켜 상태화 행위를 가진 객체로 만들고, 객체들간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법

객체지향 프로그래밍의 장단점

장점

  • 상속 캡슐화 다형성의 특징으로 코드를 재사용하거나 확장하기 좋아서 유지보수가 쉽다.
  • 관련이 많은 객체의 상호작용을 생각해 실세계에 대한 모델링을 조금 더 쉽게 해준다.
  • 캡슐화 특징으로 실제로 구현되는 부분을 외부에 드러나지 않도록 은닉하여 보안성이 높다.

단점

  • 캡슐화와 격리구조 때문에 절차지향 프로그래밍보다 실행 속도가 느리다.
  • 객체 단위의 구성으로 필요한 절차지향 프로그래밍보다 메모리 비용이 크다.

OOP(객체지향 프로그래밍, Object-Oriented Programming) 의 4가지 특징

  1. 캡슐화

    객체가 역할을 수행하기 위한 정보와 기능을 하나로 묶어서 데이터를 외부로부터 보호하는 것

    • 클라이언트에게는 인터페이스만 제공을 해서 필요한 정보만 노출하고, 실제 구현 정보는 숨겨서 기능만 사용할 수 있게 한다.
    • 필드는 private으로 접근을 막고, 메서드를 public으로 열어서 캡슐화를 사용한다.
  2. 추상화

    객체지향에서 모델링 방법을 얘기한다. 실제 현실 객체에서 필요 없는 부분은 빼고, 필요한 부분만을 추출하여 사용한다.

    즉, 객체의 공통적인 속성과 기능을 추출하여 정의하는 것을 의미한다.

    • 추상 클래스와 인터페이스로 추상화를 구현할 수 있다.
    • 어떤 객체의 행위를 추상 클래스 또는 인터페이스로 규정해 두고, 실제 구현은 구현체에서 하도록 프로그래밍을 설계할 수 있다.
  3. 상속

    상위 클래스의 특성을 하위 클래스가 물려받는 것을 말한다.

    상속을 받은 자식 클래스는 부모 클래스와 계층적 관계를 갖게 된다.

    상위 클래스에서 하위 클래스로 내려갈수록 구체화되는 것이 중요하다.

    • 부모 클래스의 메서드 또는 필드를 자식 클래스에서 접근하여 사용할 수 있다.
  4. 다형성

    하나의 메서드를 여러 가지 형태로 변화시킬 수 있는 것을 말한다.

    overriding 과 overloading을 통해 구현한다.

    • overrding : 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것 (반환값, 매개변수) 는 유지하되, 내부 구현을 재정의
    • overloading : 같은 이름의 메서드를 매개변수의 타입 또는 개수를 다르게 하여 여러 개 정의하는 것
    • 생성자 오버로딩이 있다.

객체 지향 설계 5원칙

SRP (Single Responsibility Principal) : 단일 책임 원칙

하나의 클래스는 하나의 기능만을 가져야 하고, 하나의 클래스를 변경해야 하는 이유는 하나뿐이어야 한다는 원칙

단일 책임 원칙을 지키면 객체 간의 결합이 느슨해지고, 잘 지키지 못하면 여러 클래스가 복잡하게 결합되어 변경이 일어날 때 고쳐야 하는 부분이 많아지게 됩니다.

  • 변경에 의한 연쇄 작용 감소
  • 가독성, 유지보수성 향상

OCP (Open Closed Principal) : 개방 폐쇄 원칙

확장에는 열려있고, 변경에는 닫혀 있어야 한다는 원칙

요구사항이 추가되어 기능을 확장할 때, 기존 구성 요소는 수정하지 않고 쉽게 기능을 추가할 수 있도록 설계해야 한다.

  • 객체지향의 추상화와 다형성을 활용하면 개방폐쇄 원칙을 잘 지킬 수 있다.

LSP (Liskov Substitution Principal) : 리스코프 치환 원칙

서브 클래스를 항상 상위 클래스로 교체할 수 있어야 한다는 원칙

자식 클래스는 항상 부모 클래스에서 가능한 행위를 항상 수행할 수 있어야 한다는 의미

  • 인터페이스의 구현체가 여러 개 있을 때, 구현체를 갈아 끼워도 구현체를 사용하는 곳에서는 똑같이 동작
  • 클래스나 인터페이스의 상속을 이용해 확장성을 얻을 수 있고, 이 때문에 인터페이스를 만들어 사용하는 게 좋다.

ISP (Interface Segregation Principal) : 인터페이스 분리 원칙

사용하지 않는 메서드를 가진 인터페이스는 필요한 기능만을 담은 인터페이스로 분리해서 사용하라는 원칙

클라이언트에게 꼭 필요한 기능만을 가진 인터페이스를 제공해야 합니다.

  • 특정 인터페이스가 1,2,3,4의 기능이 있는데, 클라이언트 A는 1,2의 기능을 사용하고, 클라이언트 B는 2,3,4의 기능을 사용한다면 A에게는 1,2의 기능만을 담은 인터페이스를 제공하고, B에게는 2,3,4의 기능만을 담은 인터페이스를 만들어서 제공하는 게 좋다.

DIP(Dependency Inversion Principal) : 의존 역전 원칙

하위 모듈이 변경될 때, 상위 모듈은 변경되지 않도록 설계해야 한다는 원칙

추상화(인터페이스)에 의존해야하고, 구체화(클래스)에 의존하면 안된다.

  • Spring 에서는 DI를 이용하여 DIP를 잘 지키도록 한다.
  • 상위 모듈인 Controller에서 하위 모듈인 Service 인터페이스를 의존할 때, 하위 모듈인 Service의 구현체를 변경해도 상위 모듈인 Controller는 변경되지 않도록 한다.
    • DI : Dependency Injection으로 의존성 주입
    • DIP : 의존성 역전 원칙
    • Controller에서는 @Bean으로 등록된 Service 구현체를 주입받아서 사용한다.

클래스 vs 객체 vs 인스턴스의 차이

클래스 : 객체를 만들기 위한 코드, 틀, 명세 같은 느낌

객체 : 클래스에서 선언된 모양 그대로 생성하면 객체

인스턴스 : 객체가 생성되어 메모리에 할당되면 그것이 인스턴스

인터페이스와 추상 클래스의 차이

공통점

  • new 연산자로 인스턴스를 생성할 수 없다.
  • 사용하기 위해서는 하위 클래스에서 확장/구현해야 한다.

인터페이스

  • 구현체들이 같은 동작을 한다는 걸 보장하기 위해 사용한다. → 하위 클래스가 반드시 모든 메서드를 구현해야 한다.
  • 다중 상속이 가능하고, 구현체들 간에 연관관계가 없을 수 있다.
  • 구현 내용 변경이 용이하게 하도록 하기 위해 인터페이스를 사용한다.

추상 클래스 (abstract class)

  • 객체들의 공통된 개념을 묶어서 추상화시키고, 기능 확장을 위해 사용한다.
  • 추상 클래스를 상속받는 객체들 간에는 연관관계가 있다.

좋은 객체 지향 프로그래밍이란 ?

“역할과 구현을 분리”

인터페이스를 안정적으로 잘 설계하는 것이 중요하다.

  • 실세계의 역할과 구현 이라는 편리한 컨셉을 다형성을 통해 객체 세성으로 가져올 수 있음
  • 유연하고, 변경이 용이
  • 확장 가능한 설계
  • 클라이언트에게 영향을 주지 않는 변경 가능
profile
정진 또 정진

0개의 댓글