Skip to content

Latest commit

 

History

History
106 lines (82 loc) · 12 KB

OOP.md

File metadata and controls

106 lines (82 loc) · 12 KB

객체지향언어

1. 객체지향의 특징이 무엇이 있나요?

  • 객체지향이란, 함수에 객체를 사용하여 메시지를 전달하는 것이고, 객체를 자율적인 존재로 바라보는 것입니다.
  • 객체지향의 특징에는 크게 4가지가 있습니다. 캡슐화, 상속, 다형성, 추상화 입니다.
  1. 캡슐화
  • 객체의 속성(data fields)과 행위(메서드, methods)를 하나로 묶고, 실제 구현 내용 일부를 외부에 감추어 은닉한다.
    객체는 자율적인 존재로서 동작해야하고 외부에서 직접 접근하여 객체의 상태를 변경하려고 해서는 안됩니다. 이를 방지하기 위함입니다.
  1. 상속
  • 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 것입니다.
    상속으로 인해 속성과 행위들을 간편하게 재사용하거나 반복적인 코드를 최소화 할 수 있고, 다형성을 적용할 수도 있습니다.
  • 상속은 크게 2가지로 구분됩니다.
    1. 서브타이핑
    • 서브타이핑의 경우 서브 클래스가 슈퍼 클래스를 대체할 수 없는 경우를 말합니다. 설계를 유연하게 하기 위해 사용합니다. 이를 인터페이스 상속 이라고 합니다.
    1. 서브클래싱
    • 서브클래싱의 경우 서브 클래스가 슈퍼 클래스를 대체할 수 있는 경우를 말합니다. 주로 코드의 중복 제거와 재사용이 목적입니다. 이를 구현 상속 이라고 합니다.
  1. 다형성
  • 어떤 객체의 속성이나 기능이 상황에 따라 여러가지 형태를 가질 수 있는 성질입니다.
    실제 프로그래밍에 적용한다면, 부모의 참조타입으로 자식의 인스턴스를 다루는 것을 의미합니다.
  • 이를 활용하여, 메시지 송신자의 입장에서 수신자의 분명한 구성 클래스를 알지 못하더라도 메시지를 유연하게 전달 할 수 있습니다.
  1. 추상화
  • 불필요한 세부 사항들은 제거하고 가장 본질적이고 공통적인 부분만을 추출하여 표현하는 것입니다. 프로그래밍적 관점에서는 객체의 공통적인 속성과 행위를 추출하는 것입니다.

2. SOLID 원칙

  • SOLID 원칙은 객체 지향 설계의 다섯 가지 기본 원칙을 말합니다. SRP, OCP, LSP, ISP, DIP로 구성되어 있습니다.
  1. SRP(Single Responsibility Principle, 단일책임원칙)
  • 한 클래스는 하나의 책임만 가져야 한다는 원칙
  • 이 원칙은 설계 당시에 제대로 지켜져있는지 알기 쉽지 않고, 리팩토링을 하는 과정에서 해당 클래스에 많은 변경사항이 발생된다면 단일 책임 원칙에 위배 된 것이므로 올바른 설계가 되었는지 다시 생각해봐야 합니다.
  1. OCP(Open Closed Principle, 개방폐쇄원칙)
  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
  • 실제 내부 구성 코드를 변경해서 소프트웨어를 확장하는 것이 아닌, 다형성을 이용해서 알고리즘 군을 형성하고 외부에서 구성 클래스만 추가하여 유연하게 수정하는 방식입니다.
  • 이때, 확장과 변경의 기준은 객체 자신의 기준입니다. 객체 외부에서는 확장을 위해 변경이 발생할 수 있습니다.
  1. LSP(Liskov Substitution Principle, 리스코프 치환 원칙)
  • 프로그램 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
  • 다른 말로 슈퍼타입을 서브 타입이 대체 가능한 것을 의미합니다.
  1. ISP(Interface Segregation Principle, 인터페이스 분리 원칙)
  • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
  • 역할을 여러 개로 나눈다면, 다형성으로 인해 유연한 설계가 가능합니다.
  1. DIP(Dependency Inversion Principle, 의존관게 역전 원칙)
  • 추상화에 의존하고, 구체화에 의존하면 안된다.
  • 이를 이용해, 메시지를 유연하게 전송할 수 있고, 수신자의 입장에서 해당 객체를 유연하게 받기 위해 사용하는 의존성 주입이 이 원칙을 따르는 방법 중에 하나입니다.

2. 개발을 할 때 객체지향적으로 프로그래밍을 하는가. 만약에 했다면 객체지향의 어떤 특징을 이용하여 적용을 하였는가.

  • 실제 프로젝트에서 인프라 관련해서 수정이 발생하는 부분이 있었고, 이를 객체지향의 다형성과 OCP, ISP, DIP를 이용하여 인프라에 따라 다른 구성 클래스가 적용될 수 있도록 인터페이스를 설계하여 구현한 적이 있습니다. 이를 이용해 실제 코드를 건드리지 않고 유연하게 구성 클래스를 교체하여 프로젝트의 코드를 유연하게 작성 할 수 있었습니다.

Q) 개방 폐쇄 원칙과 다형성의 관계에 대해서 설명해주세요.

  • 개방 폐쇄 원칙은 객체 내부의 코드는 변경하지 않고, 확장이 가능하도록 하는 것입니다. 이를 가능하게 하기 위해서 다형성이 필요합니다. 주로 개방 폐쇄 원칙은 DIP와 많이 따라다니게 되는데 의존 주입 방식이 OCP를 지키면서 DIP도 지키는 방식이기 때문입니다. 의존 주입할 구성 클래스에 대상을 추상 클래스로 받도록 하고, 외부에서 메시지를 송신할 때 구성 클래스를 전송함으로써 객체 내부에서는 자율적으로 구성 클래스에 맞게 행동 할 수 있습니다.
  • 즉, 객체의 속성이나 기능이 상황에 따라 여러가지 형태를 가질 수 있다는 다형성의 특징을 사용한 것으로 볼 수 있습니다.

3. 추상클래스와 인터페이스의 공통점과 차이점에 대해서 설명해주세요.

[공통점]

  • 추상클래스와 인터페이스 모두 추상 메서드를 선언하고 이를 상속 혹은 구현을 해야만 동작이 가능하고, 생성자를 통해 각 추상클래스와 인터페이스는 생성 할 수 없다는 공통점을 가지고 있습니다.

[차이점]

  • 자바에서 클래스는 단일 상속밖에 안되기 때문에, 추상 클래스는 단, 하나만 사용할 수 있으며 인터페이스는 다중 구현이 가능하기 때문에 여러 개의 인터페이스를 구현이 가능합니다.
  • 추상 클래스는 추상 메서드를 제외하고 메서드나 변수의 선언이 가능하기 때문에 변수 혹은 메서드의 재사용성이 높아진다는 장점이 있습니다.
  • JDK 1.8 이후로 인터페이스에 default 키워드 및 상수를 추가할 수 있도록 변경되었습니다.
    이에 따라, 인터페이스도 메서드를 공통된 메서드가 겹칠 수 있는 두 가지 상황이 있습니다.
    1. 인터페이스 간의 default 메서드가 중복되어 충돌 됐을 경우
    • 오버라이딩을 통해서 해결 할 수 있습니다.
    1. 조상메서드와 default 메서드가 충돌 됐을 경우
    • default 메서드는 무시하고 조상 메서드를 상속합니다.

4. 캡슐화의 특징인 정보은닉과 연계해서 프로젝트 도중 캡슐화의 장점을 겪은 경험이 있는가

  • 프로젝트간 객체에게 메시지를 전달하는 과정에서 어떠한 행위를 수정하지 않아도 되도록 하고, 이 과정에서 메시지 수신자 내부에서 요청을 받은 행위에 대한 수정이 있더라도 송신한 객체는 그 코드 부분을 건드리지 않고도 기능을 확장 할 수 있었습니다.

Q) 인터페이스의 default 메서드가 나오게 된 계기에 대해서 설명해주세요.

  • 인터페이스의 가장 큰 단점은 새로운 추상 클래스가 추가된다면 인터페이스를 구현한 구성클래스들이 해당 공통 로직을 전부다 구현해줘야 한다는 단점이 있었습니다.

  • 이러한 불편함을 개선하기 위해서 default 메서드를 추가함으로써 새로운 기능이 추가되더라도 구성클래스들이 해당 기능을 구현하지 않아도 동작이 가능해졌습니다.

    Q) 인터페이스에서 default 메서드를 사용하게 되면 추상 클래스와 크게 다르지 않을 것 같은데 차이점이 있을까요?

    • 추상클래스와 인터페이스의 목적이 다릅니다. 추상 클래스는 코드의 중복을 제거하고 부모의 기능을 재사용을 하기 위해 사용하며, 단일 상속밖에 안된다는 단점이 있고, 인터페이스는 코드의 유연한 설계를 위해 사용하는 것이고, 다중 구현이 가능합니다. 따라서, 상황에 맞게 적절하게 사용 할 필요가 있습니다.

5. 스프링의 AOP에 대해서 설명해주세요.

  • 애플리케이션은 크게 핵심 기능과 부가 기능으로 나눌 수 있습니다. 여기서 AOP(Aspect-Oriented-Programming, 관점 지향 프로그래밍)는 부가 기능을 추가하기 위해 도입된 개념입니다. 프록시를 통해서 구현이 가능하며 주로 횡단 관심사 관점으로 달리 보는 것입니다.
  • AOP를 적용하기 위해서 필요한 것은 크게 2가지입니다. 첫 번째는 Point Cut이며, 두 번째는 Advice입니다.
  1. Point Cut : AOP의 적용 범위를 설정하기 위해 사용합니다. 즉, 필터가 목적입니다.
  2. Advice : 프록시 패턴 혹은 데코레이터 패턴을 적용하는 주요 로직에 해당하는 부분입니다.
  • 그리고 위의 두 가지를 합친 것을 Advisor라고 하며, 스프링의 후처리기는 Advisor를 찾아 적용하는 방식입니다.

Q) AOP는 객체지향의 특징에서 어떤 부분과 연관지을 수 있을까요?

  • AOP는 기본적으로 프록시를 사용합니다. 프록시란 주 기능을 수행하기 위해 부가적인 기능을 수행할 수 있도록 도와주는 것인데, 이 과정에서 구성 클래스의 로직을 건드리지 않고 외부에서 어떤 코드를 추가하여 기능을 확장 할 수 있으므로, 개방폐쇄원칙과 가장 큰 연관이 있다고 생각합니다.

  • 추가적으로 해당 부가기능을 수행하는 프록시는 어떠한 부가기능을 추가하기 위해 해당 기능만을 담당하기 때문에 단일 책임 원칙과도 큰 연관이 있다고 생각합니다.

    Q) DIP에 대한 예시 하나만 설명해주세요.

    • DIP를 활용하면 주된 방식 중 하나인 DI(Dependency Injection, 의존 주입)가 있습니다.
    • 이를 이용해 구성 클래스가 유연하게 교체가 가능하도록 설계가 가능합니다.

6. 객체지향적으로 개발을 하기 위해 제일 고려해야 하는 것은 무엇인가요?

  • 사용자의 요구사항에 대해서 만족시킬 수 있도록 도메인적 관점에서 바라보고, 설계 시 그 행위에 초점을 두어야 한다고 생각합니다.
  • 행위에 초점을 두었을 때, 해당 객체들이 메시지를 송신하는데에 있어서 각 객체가 서로 어떻게 연관이 되어야 하는지 갈피가 잡히고, 여기서 행동을 하는데에 필요한 것을 상태로 추가하여 설계해야 합니다.

7. 업캐스팅과 다운캐스팅에 대해서 설명해주세요.

  • 부모의 참조변수를 가지고 자손 타입의 인스턴스 객체를 참조하는 경우에 자손 타입의 인스턴스에서 부모 타입의 인스턴스로 형변환 하는 것업캐스팅이라고 하며, 부모 타입의 인스턴스에서 자손 타입의 인스턴스로 형 변환 하는 것다운 캐스팅이라고 합니다.

Q) 부모와 자식이 있을 때, 자식 클래스를 생성하는 경우 어떤 클래스가 먼저 생성될까요?

  • 자식 클래스의 생성자에는 기본적으로 부모 클래스의 생성자를 생성자의 최상위에 호출을 해주어야 하기 때문에, 부모 클래스가 먼저 생성되고 그 이후에 자식 클래스가 생성됩니다.