[OOP] 객체지향 프로그래밍 과 캡슐화

SJ.CHO·2024년 9월 23일

객체지향

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

  • 각자 책임을 가지는 객체들이 서로 협력함으로써 문제를 해결하는 것

    • 협력에 참여하는 객체는 전문가로써 각자의 책임 을 가진다.
    • 목표는 하나의 객체가 지휘하는것이 아닌 객체들간의 협력으로 이뤄진다.
    • 내가 할수없는 기능은 다른객체에게 요청 해결 하고 처리는 전적으로 위임 한다. (Message)
    • 책임을 가지는 객체들은 자율성(독립적 흐름)을 가지고 책임을 수행하고 전문성을 가진다.
  • 설계를 하며 어떻게 작성할지보단 어떤흐름과 책임이 필요하지로 분류한다.

의존성과 변경의 전파

  • 의존성 : 객체가 다른객체에 대한것을 알고있는 것 으로 해당 객체에대해 의존성이 생김 (협력을 위해)
    • 의존 관계가 생겼을시 Code의 변경을 전파 할 수 있는 문제가 존재. 유지보수성이 떨어짐.
    • 최대목표 : 의존성이 변경을 전파하는 것을 최소화 하는것을 목적이 중요. (객체지향의 최대근본문제)

핵심은 캡슐화

  • 은닉이 핵심이 아닌 은닉할 필요성 에 대한것.
  • Client 가 구체적인것에 의존하지못하도록 숨기고 추상적인것 만 의존하도록 유도 및 설계가 가능하다.
    • 구체적인 것 : 변경 가능성이 높은것. 메소드 동작에 대한 HOW , 주로 메소드 Body 부분
    • 추상적인 것 : 변경 가능성이 낮은것. 메소드 이름, 파라미터, 반환값 등 What
    • 낮은 수준 높은 수준이라고도 표현. 상대적이고 상황따라 판단이 필요하다. (적당한 추상화 수준)
  • 구체적인것을 의존할 수록 결합도가 높아지고 변경 전파성이 높아진다. 변경에대해 경직도가 높아짐.

HOW?

  • 캡슐화의 본질 및 방향성과 관점이 중요하다.
  1. 자주변경되는 것와 그렇지않은것을 분리.
  2. 자주변경되는 구체적인것을 Client 객체로부터 은닉.
  • 호출하는 쪽 Client 객체의 코드를 먼저 작성. (구체적인것을 Client는 모르기때문에 의존이 불가능)

QUIZ

  • BaseballGame 객체를 사용할경우 answer 라는 구체적인것에 의존하기 때문에 answer의 결과가 필요한것이 아니라 answer의 대한 게임의 판결을 받을수록 유도해야함.
  • answer(구체적 요소) 가 외부의 노출될 가능성이 높아진다. 또한 협력에 어울리지않는 객체가 생성가능성이 있음 (행위보단 데이터에 집중되는 형태의 코드 작성 가능성).
  • 가능하면 객체 그래프를 따라서 객체를 get,get,get 하는 형태로 작성하지 말고 바로 접근할 수 있는 객체의 메서드를 호출하는 형태로 코드를 작성 (데이터보다 행위에 초점을 맞춘 코드 작성)
acc.getDate().isAfter(now) 이렇게 말고
acc.isExpired() 이렇게 작성

참조 : https://m.blog.naver.com/fbfbf1/222798772563

추상화 타입

  • 변경은 객체의 코드가 변경될수도 있지만 객체자체가 다른객체 로 대체/확정되는 변경이 존재.
  • 추상클래스 혹은 인터페이스등 객체가 변경되더라도 해당 추상화를 구체화하여 행동을 보장한다면 Client 객체는 변경이 전파되지않는다.
  • 추상적인 것들만 모아서 단계를 분리하여 상위타입화. Client 객체는 추상화 타입만 알더라도 동작이 가능하다!
    • 행위에대한 기능만 필요하면 InterFace / 다른 값이 필요하다면 추상클래스
  • 변경에 대한 범위를 객체 단위로 변경성을 높힘. 관심사 에 대한 분리 자율성 확보
  • 의존성의 대한 역전 DIP 가 가능하다.

    DIP (Dependency Inversion Principle) : 객체에서 Class 를 참조해야할때 Class 를 직접참조하는 것이 아닌 대상의 상위요소 추상클래스 or 인터페이스 로 참조하라는 원칙
    참조 : https://inpa.tistory.com/entry/OOP-%F0%9F%92%A0-%EC%95%84%EC%A3%BC-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-DIP-%EC%9D%98%EC%A1%B4-%EC%97%AD%EC%A0%84-%EC%9B%90%EC%B9%99

타입계층

  • 상속을 통해 타입계층 을 만들어낼 수 있다. 추상화, 다형성을 구현하는데 문법적 기반을 만들어준다.
  • 부모타입이 물려준 행위를 자식타입이 반드시 행동을 보장 해준다.
  • 다형성에 필요한 형변환문법적인 보장 을 해준다.

다형성

컴파일 의존성 vs 런타임 의존성

  • 시점에 따라 의존성에대한 시점이 달라짐 : 동적 바인딩
  • 문법적 보장을 통해 다양한 자료형에 속하는것을 허가 되는 성질. 행위호환성 을 보장한다.
  • 동적 바인딩은 코드의 흐름을 찾기가 어렵게 된다. 가독성 DOWN, 생산성 DOWN

의존성주입(DI)

  • Client 객체가 의존하고자 하는 객체를 직접생성하는게 아닌 외부에서 주입받는 것.
  • Client가 추상화 타입을 의존하기위해선 의존성주입이 필요.

IOC 와 DI이 객체지향적으로 어떤 도움이 될까?

  • DI : Client 객체가 의존하고자하는 객체를 직접생성시 구체적인객체를 의존하게된다.
    • 객체에대한 변경성이 전파됨으로 결합도가 높아지고 캡슐화가 깨지며 크게는 OOP원칙을 위배하게된다.
    • 외부에서 의존성을 주입 받는다면 Client 객체는 추상화타입을 의존하기에 결합도가 낮아진다. 유연한 구조의 프로그램설계가 가능해진다.
    • 이를 통해 컴파일시점에선 추상화타입을 의존하지만 런타임 시점에선 구체적 객체를 의존하게 만들수 있다.
  • IOC : 개발자가 프레임워크의 도움없이 의존성을 관리하기에는 코드의 복잡도와 영향성이 너무 높다.
    • IoC Container 를 사용시 객체의 대한 생성 관리를 필요한시점에 DI를 해줄수있다.
    • 이를 통해 프레임워크의 관심사와 개발자 로직의 관심을 분리해 결합도를 낮추며 유연한 코드를 작성할수 있다.
    • 결과적으론 SOLID 원칙 중에서 특히 '의존성 역전 원칙(DIP)'을 잘 따를 수 있게 해 준다.

요약

참조 : https://velog.io/@slolee/%EC%BA%A1%EC%8A%90%ED%99%94%EC%99%80-%EC%B6%94%EC%83%81%ED%99%94-%ED%83%80%EC%9E%85

profile
70살까지 개발하고싶은 개발자

0개의 댓글