모의 면접 (1)
스파르타 내일 배움 캠프 모의 면접 진행 내용에 대해 정리한 글입니다.
객체 지향적 프로그래밍에서 관심사를 분리(Controller,Service,Repository)가 필요한 이유
Service와 Repository를 따로 만들지 않아도 Controller에서 모든 응답을 처리할 수는 있지만 객체지향 프로그래밍에 부합하지 않습니다.
객체지향 프로그래밍의 핵심 원칙 중 하나인 단일 책임 원칙 (Single Responsibility Principle, SRP)에 따르면 하나의 클래스는하나의 책임만 가져야하기 때문입니다. 따라서 Service와 Repository를 따로 분리함으로써 각각의 계층이 하나의 명확한 책임을 지니게 됩니다.
그래서 각 Layer간의 관심사를 하나로 줄여서 계층의 응집도를 높이고 유지 보수성을 높이는 효과를 얻기 위해 관심사 분리가 필요합니다.
이로 인해 현업에서는 코드의 추가나 변경 요청이 발생하거나 문제가 발생했을 때, 해당 Controller 클래스를 구현한 개발자가 퇴사한다고 해도 각 계층이 명확한 책임을 가지게 되므로 코드를 이해하기 쉬워집니다. 특정 계층의 로직을 변경해야 할 경우에도 다른 계층에 미치는 영향이 최소화하여 유지보수가 용이해집니다. 마지막으로, 각 계층을 독립적으로 테스트할 수 있어 문제를 더 쉽게 식별하고 해결할 수 있습니다.
사용자의 요청을 받고 응답을 반환하는 역할을 Controller로 나누고 비즈니스 로직을 처리하는 역할을 Service로 하고 데이터 접근 로직을 처리하는 역할을 Repository에서 합니다.
Restful API를 사용하는 이유, 정의, 장점
API란 Application Programming Interface의 약자로 두 애플리케이션이 서로 통신하는 방법을 정의한 것을 의미합니다.
예를들어 폰의 버튼으로 소리를 조절하거나 전원을 켜고 끄는 것처럼 폰 내부가 어떻게 동작하는지는 대해 알지 못해도 인터페이스를 통해서 쉽게 사용할 수 있습니다. 이러한 인터페이스가 간단하고 직관적일수록 훨씬 사용하기 편할 것입니다.
다시 말해, API는 어플리케이션 간에 지정된 형식으로 요청과 응답을 할 수 있도록 연결하는 것입니다.
RESTful API는 REST 아키텍처 스타일의 설계 원칙을 준수하는 API입니다.
인터넷 식별자 URI와 HTTP 프로토콜을 기반으로 하는 웹 서비스를 위한 API입니다.각 요청 메시지가 어떤 동작이나 정보를 위한 것인지 그 요청 메세지 자체만으로 파악할 수 있습니다. 이는 HTTP 요청을 할 때 어떤 URI에 어떤 메서드를 사용할지에 대한 개발자들 사이에서 널리 사용되어지는 약속입니다.HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용 가능하며, 인프라를 별도로 구축할 필요가 없습니다. 또한 RESTful API 메시지가 의도하는 바를 명확하게 나타내므로 쉽게 파악할 수 있습니다. 마지막으로 언어에 구애받지 않기 때문에 애플리케이션이 사용된 언어와 상관없이 다른 애플리케이션과 통신할 수 있는 장점이 있습니다.
객체지향 프로그래밍(Object Oriented Programming, OOP) 이 무엇이고 어떻게 활용하는가?
객체지향 프로그래밍은 절차지향 프로그래밍의 한계를 극복하기 위해 등장했습니다. 절차지향 프로그래밍은 함수와 데이터를 분리하여 관리하므로 구조가 복잡해지고 가독성과 유지보수가 어렵습니다.
예를 들어 도서 관리 프로그램을 절차지향으로 개발한다고 할 때 ‘책’이라는 데이터와 관련 함수를 따로 관리해야 하므로 연관성을 즉시 파악하기 어렵습니다. 다시 말해 논리적으로 묶여있을 수 없는 구조이기 때문에 동작이 추상적입니다.
따라서 이를 해결하기 위해 ‘객체지향 프로그래밍’이 등장하게 되었습니다. 객체지향 프로그래밍은 어떤 개념에 대한 데이터와 함수를 ‘객체’ 형태로 함께 묶어 관리합니다. 객체 내부에는 데이터 필드와 이를 조작하는 메서드가 함께 존재합니다.
예시로 든 도서 관리 프로그램도 객체지향으로 구현하게 되면 책의 제목, 저자, 페이지수와 같은 자료형 필드와 대출하기, 반납하기 등의 메서드를 책이라는 객체에 같이 묶어서 관리하는 것이 가능해지고 이렇게 되면 추상적이었던 동작도 직관적으로 보이게 되어 코드 가독성이 증가합니다. 결론적으로 객체 간의 독립성이 뚜렷하게 생기고, 중복되는 코드의 양이 줄어서 유지보수에 용이해질 것입니다.
객체지향 프로그래밍 특징
- 추상화
객체들이 공통적으로 필요로 하는 속성이나 동작을 하나로 추출해내는 작업입니다.
- 예시를 들겠습니다. 람보르기니, 페라리, 포르쉐 등 모두 ‘평생 못 사는 차’라는 공통점이 있습니다.
- ‘평생 못 사는 자동차’라는 추상화 집합을 만들고 평생 못사는 자동차들이 가진 공통적인 특징들(매우 비싼 가격, 배기음)을 만들어 활용할 수 있습니다.
- ‘맥라렌’과 같은 다른 ‘평생 못 사는 자동차’가 추가될 수 있는데 이때 추상화로 구현해 놓으면 다른 코드는 건드리지 않고 추가로 만들 부분만 새로 만들어 주면 되는 장점이 있습니다.
- 캡슐화
정보 은닉화를 통해 높은 응집도와 낮은 결합도를 유지할 수 있도록 설계하는 것입니다. 객체의 내부 구현을 감추고, 필요한 부분만 외부에 노출하여 정보 은닉을 합니다. 이를 통해 외부에서 무언가 잘못 건드려 객체를 손상시키는 일을 방지할 수 있습니다.
결합도란 어떤 기능을 실행할 때 다른 클래스나 모듈에 얼마나 의존적인지를 나타내는 지표입니다. 객체 간의 독립성을 강조하기 위해 객체지향 프로그래밍이 등장했는데 결합도가 높으면 객체지향으로 설계하는 의미가 있을까요? 따라서 독립적으로 만들어진 객체들 간의 의존도를 최대한 낮게 만드는 것이 중요합니다.
높은 응집도와 늦은 결합도는 ‘은닉화’를 통해 이루어낼 수 있습니다. 외부에서 접근할 필요가 없는 것들은 접근 지정자를 private로 두어 접근에 제한을 두고 외부 객체는 객체 내부의 구조를 모르게 하여 해당 객체가 노출해서 제공하는 필드와 메서드만 이용할 수 있도록 하여 의도하지 않은 동작 오류를 방지하고 유지보수 효율을 높일 수 있습니다.
- 상속
- 부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용하는 것입니다.
상속을 통해 코드 재사용성을 높이고, 부모 클래스와 자식 클래스 간의 관계를 형성합니다. 자식 클래스는 부모 클래스의 기능으 륵대로 사용할 수 있고, 필요에 따라 기능을 확장하거나 변경할 수 있습니다.
- 이때 앞서 말한 ‘평생 못 사는 자동차’가 부모 클래스로 정의되어있고 공통 속성과 메서드를 가집니다. 자식 클래스에 해당하는 람보르기니, 페라리, 포르쉐 등은 부모 클래스의 속성과 메서드를 물려받고, 필요에 따라 재정의(오버라이딩)할 수 있습니다.
클래스의 속성과 메서드를 재사용함으로써 코드 재사용이 가능해지고 계층적 구조가 됩니다. 또한 부모 클래스의 속성이나 메서드가 변경되면 이를 상속받는 모든 자식 클래스에 자동으로 적용되기 때문에 유지보수가 용이합니다.
- 다형성
- 서로 다른 클래스의 객체가 같은 동작 수행 명령을 받았을 때, 각자의 특성에 맞는 방식으로 동작하는 것입니다.
이를 통해 코드의 유연성과 간결함을 제공합니다.
- ‘평생 못 사는 차’라는 개념을 상속(일반화)하여 람보르기니, 페라리 등 객체를 만들었는데 ‘평생 못 사는 차’라는 클래스의 ‘배기음 재생’이라는 메서드를 실행했을 때 자식 클래스들이 각기 다른 배기음의 소리를 내는 것이 다형성이 부각된 부분입니다.
- 추상화
Setter 메서드를 함부로 사용하면 안 되는 이유
Setter 메서드를 함부로 사용하면 객체 지향의 핵심인 정보 은닉을 해치게 되어 객체가 생성된 이후에도 상태를 변경할 수 있습니다. 이로 인해 외부에서 객체의 상태를 알게 되거나 객체의 상태를 그대로 수정하게 되고, 객체의 상태가 변경되면 의도하지 않은 동작을 수행하여 문제가 발생할 수 있습니다.
** Setter 메서드 예방하는 방법**
- 불변 객체를 사용하여 생성 이후 상태를 변경할 수 없도록 설계합니다.
- 상태 변경이 필요한 경우, 단순한 Setter 메서드 대신 내부 로직을 포함한 의미 있는 메서드를 제공하여 무결성을 유지합니다.
- 객체를 생성할 때 생성자나 빌더 패턴을 사용하여 초기 상태를 설정합니다.
NoSQL, RDBMS가 무엇인가, 어디에 사용되는가(아는대로 설명)
DB란 컴퓨터 시스템에 전자 방식으로 저장된 데이터의 체계적인 집합을 의미합니다.
DBMS란 Database를 관리하고 운영하는 소프트웨어를 의미합니다.
RDBMS는 DBMS 앞에 R ( Relational ) 이 추가되어 관계형 데이터베이스 관리 시스템이라고 합니다. 테이블이라는 최소 단위로 구성되며 열과 행으로 이루어져 있습니다. 관계형 데이터베이스(RDMBS)에서는 이러한 관계를 나타내기 위해 외래 키(foreign key)라는 것을 사용하고 이러한 테이블간의 관계에서 외래 키를 이용한 테이블 간 Join이 가능하다는 게 RDBMS의 가장 큰 특징입니다
데이터는 사전에 정의된 스키마에 따라 구조화되어 저장되므로 명확한 데이터 구조를 보장합니다. 또한 관계는 각 데이터를 중복없이 한 번만 저장할 수 있다. SQL을 사용하여 데이터를 조작하고 관리합니다.
NoSQL은 비관계형 데이터베이스로 RDBMS와는 달리 테이블 간 관계를 정의하지 않습니다.
유연한 스키마를 가지고 있어서 데이터 모델이 유동적으로 변경 가능하므로 새로운 필드나 구조를 추가하거나 수정할 수 있기 때문에 개발자들이 빠르게 변경된 요구사항에 대응할 수 있습니다.
NoSQL은 대부분 분산 환경에서 동작하도록 설계되었습니다. 이는 수평적 확장이 가능하며 대용량 데이터 처리에 유리합니다.
데이터 테이블은 그냥 하나의 테이블이며 테이블 간의 관계를 정의하지 않아 일반적으로 테이블 간 Join도 불가능합니다.
RDBMS는 정형화된 데이터를 다루는 전통적인 시스템에 적합하며, NoSQL은 대규모 데이터나 유연한 데이터 모델이 필요한 경우에 적합합니다.
RDBMS, NoSQL 언제 사용해야 될까?
RDBMS는 데이터 구조가 고정되어 있고, 변경이 잦지 않을 때 사용합니다. 또한 ACID 특성을 준수하며 데이터 일관성과 안전성이 요구되는 경우에는 RDBMS를 사용합니다. 데이터 간의 관계가 복잡하고, 이에 대한 변경이 자주 발생하는 경우 RDBMS를 사용합니다.
NoSQL은 데이터의 구조가 유연하고 동적으로 변경될 수 있는 경우 NoSQL을 사용합니다. 또한 NoSQL은 분산 환경에서 대규모 데이터를 처리하고 수평적으로 확장할 수 있는 장점이 있습니다. 따라서 대용량 데이터 처리가 필요한 경우에는 NoSQL을 사용합니다.