1. 디자인 패턴이란?
디자인 패턴에 대해 설명해 주세요
- 프로그램을 설계할 때 발생했던 문제점들을 쉽게 해결할 수 있도록 '규약' 형태로 만들어 놓은 것을 의미합니다.
- 디자인 패턴에는 싱글톤 패턴, 팩토리 패턴, 전략 패턴, 옵저버 패턴, 프록시 패턴, MVC 패턴 등이 있습니다.
2. 싱글톤 패턴
싱글톤 패턴의 정의와 장단점에 대해 말해주세요
- 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴입니다.
- 하나의 인스턴스를 여러 모듈에서 공유하기에 인스턴스 생성 비용이 줄어드는 장점이 있습니다.
- 그렇기에 의존성이 높아져서 모듈간 독립적으로 테스트를 해야 하는 단위 테스트를 수행하기 어렵다는 단점이 있습니다.
- 이러한 높은 의존성을 의존성 주입(Dependency Injection)을 통해 모듈 간의 결합을 조금 더 느슨하게 만들 수 있습니다.
의존성 주입에 대해 설명해 주세요
- 의존성이란, A가 B에 의존성이 있다면 B의 변경 사항에 대해 A 또한 변해야 된다는 것을 의미합니다.
- 이때 메인 모듈이 직접 하위 모듈에 의존성을 주기보다는, 중간에 의존성 주입자가 이러한 역할을 가로채 메인 모듈이 간접적으로 하위 모듈에 의존성을 주입하는 방식을 의미합니다.
- 그러므로 모듈을 쉽게 교체할 수 있는 구조가 되어 테스팅하기 쉽고, 추상화 레이어를 기반으로 구현체를 넣어주게 되어 의존성 방향이 일관되고 애플리케이션을 쉽게 추론할 수 있다는 장점이 있습니다.
- 하지만 모듈들이 더욱더 분리되므로 클래스 수가 늘어나 복잡성이 증가될 수 있다는 단점이 있습니다.
싱글톤 패턴을 자바에서 어떻게 구현할 수 있는지 설명해 주세요
- 크게 3가지의 단계로 구현할 수 있습니다.
- 생성자를 private으로 제한하여 외부에서 생성할 수 없게 만듭니다.
- private static으로 클래스에 오직 하나만 존재하는 인스턴스를 만듭니다.
- 해당 인스턴스를 외부 클래스에서 접근할 수 있도록 public static으로 해당 인스턴스를 반환하는 get 함수를 만듭니다.
싱글톤 패턴이 사용되는 예시를 들어주세요
- 데이터베이스 연결 모듈에 사용됩니다. DB 연결 과정은 부하가 크기에, 한 번 연결된 객체를 재사용하여 애플리케이션 전체에서 하나의 연결만을 유지하는 것이 효율적입니다.
3. 팩토리 패턴
팩토리 패턴에 대해 설명해 주세요
- 팩토리 패턴은 객체 생성 부분을 떼어내 추상화한 패턴으로, 부모 클래스에서 중요한 뼈대를 잡고 자식 클래스에서 객체 생성에 관한 구처젝인 내용을 결정하는 패턴입니다.
- 이때 부모 클래스에서 인스턴스를 생성하는 것이 아니라, 자식 클래스에서 생성한 인스턴스를 부모 클래스에 주입하여 의존성 주입이라고 볼 수도 있습니다.
- 부모, 자식 클래스로 분리되어 있어 느슨한 결합을 가지며 객체 생성 로직이 따로 떼어져 있어 리팩토링에 유리하고 유지 보수성이 증가한다는 장점이 있습니다.
(바리스타 공장에서 라떼 레시피, 아메리카노 레시피, 우유 레시피 만들기 예제)
4. 전략 패턴
전략 패턴에 대해 설명해 주세요
- 전략 패턴은 객체의 행위를 바꾸고 싶은 경우, 직접 수정하지 않고 전략이라고 부르는 '캡슐화한 클래스'를 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴입니다.
- 캡슐화한 클래스들은 동일한 인터페이스를 상속 받아 각자 전략을 구체화하며, 필요에 따라 클래스를 변경하여 사용할 수 있어 유지 보수이 증가합니다.
- 캡슐화는 서로 연관있는 속성과 기능들을 하나의 캡슐로 만들어 데이터를 보호하는 것을 의미합니다.
- 컨텍스트는 개발자가 어떠한 작업을 완료하는 데 필요한 모든 관련 정보(도메인 지식, 구현해야 하는 비즈니스 로직)를 의미합니다.
전략 패턴이 사용되는 예시를 들어주세요
- Node.js에서 인증 모듈을 구현할 때 쓰는 미들웨어 라이브러리인 passport가 있습니다.
- 여러 가지 '전략'을 기반으로 인증할 수 있게 합니다. (서비스 내 회원가입된 아이디와 비밀번호 기반으로 인증하는 LocalStorage 전략, SNS 등 다른 서비스를 기반으로 인증하는 OAuth 전략 등)
5. 옵저버 패턴
옵저버 패턴에 대해 설명해 주세요
- 주체가 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 패턴입니다. 옵저버들은 객체의 상태 변화에 따라 추가적인 변화 사항이 생기는 객체들을 의미합니다.
- 주체와 객체를 따로 두지 않고, 상태가 변경되는 객체를 기반으로 구축하기도 합니다.
- 개방 폐쇄 원칙을 준수하여 느슨한 결합으로 객체간 의존성을 낮출 수 있다는 장점이 있습니다.
옵저버 패턴이 사용되는 예시를 들어주세요
- 트위터 같이 주체를 팔로우하고 있으면, 주체가 포스팅을 올리면 팔로워들에게 알림이 가는 시스템을 구현하는 데 사용될 수 있습니다.
- MVC 패턴에서 모델에 변경 사항이 생기면, update() 메소드를 기반으로 여러 뷰들에게 알려줄 때 사용될 수 있습니다.
- Vue.js 프레임워크에서 ref나 reactive 기능을 사용하여 해당 값이 변경되면 자동으로 DOM에 있는 값이 변경되는데, 이는 프록시 객체를 이용한 옵저버 패턴을 이용하여 구현한 것입니다.
프록시 객체에 대해 설명해 주세요
- 프록시 객체는 어떠한 대상의 동작의 작업을 가로챌 수 있는 객체를 의미합니다.
- 자바스크립트에서 프록시 객체는 두 개의 매개변수를 가집니다.
target(프록시 할 대상), handler(target 동작을 가로채고 어떠한 동작을 할 것인지가 설정되어 있는 함수)
- 프록시 객체는 프록시 패턴이 녹아들어 있는 객체입니다.
6. 프록시 패턴과 프록시 서버
프록시 서버에 대해 설명해 주세요
- 프록시 서버는 서버와 클라이언트 사이에서, 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램을 의미합니다.
프록시 서버가 사용되는 예시를 들어주세요
(1)
- 주로 Node.js 서버 앞단의 프록시 서버로 활용되는 Nginx가 있습니다. Nginx를 통해 Node.js의 버퍼 오버플로우 취약점을 예방할 수 있고, 익명의 사용자가 직접적으로 서버에 접근하는 것을 차단하며 실제 포트를 숨길 수 있습니다. 또한 정적 자원을 gzip 압축하거나 메인 서버 앞단에서의 로깅을 할 수 있도록 합니다.
버퍼 오버플로우란?
- 버퍼는 보통 데이터가 저장되는 메모리 공간으로, 버퍼 오버플로우는 메모리 공간을 벗어나는 경우를 의미합니다. 이때 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하기도 합니다.
gzip 압축이란?
- 인터넷에서 데이터를 압축해 전송하기 위한 응용 소프트웨어입니다.
(2)
- 전 세계적으로 분산된 서버가 있고, 이를 통하 어떠한 시스템의 콘텐츠 전달을 빠르게 할 수 있는 CDN 서비스인 CloudFlare가 있습니다.
- CloudFlare는 웹 서버 앞단에 프록시 서버로 두어 DDOS 공격 방어나 HTTPS 구축에 쓰입니다. 또한 서비스를 배포한 후 의심스러운 트래픽이 급증하면 많은 클라우스 서비스 비용이 발생할 수 있는데, CloudFlare가 의심스러운 트래픽인지 먼저 판단해 CAPTCHA 등을 기반으로 이를 일정 부분 막아주는 역할도 수행합니다.
CDN이란?
- Content Delivery Network
- 각 사용자가 인터넷에 접속하는 곳과 가까운 곳에서 콘텐츠를 캐싱 또는 배포하는 서버 네트워크를 말한다. 이를 통해 사용자가 웹 서버로부터 콘텐츠를 다운로드하는 시간을 줄일 수 있습니다.
DDOS 공격이란?
- 짧은 기간 동안 네트워크에 많은 요청을 보내 네트워크를 마비시켜 웹 사이트의 가용성을 방해하는 사이버 공격 유형입니다. CloudFlare는 의심스러운 트래픽을 자동으로 차단해 DDOS 공격을 방어합니다.
HTTPS 구축
- 서버에서 HTTPS를 구축할 때 인증서를 기반으로 구축할 수도 있습니다. 하지만 CloudFlare를 사용하면 별도의 인증서 설치 없이 좀 더 손쉽게 HTTPS를 구축할 수 있습니다.
(3)
- 프론트엔드 개발 시 프론트엔드 서버를 만들어서 백엔드 서버와 통신할 때 주로 CORS 에러를 마주치는데, 이를 해결하기 위해 프론트엔드에서 프록시 서버를 만들기도 합니다.
- 예를 들어 프론트엔드에서는 127.0.0.1:3000으로 테스팅을 하는데, 백엔드 서버는 127.0.0.1:8080이라면, 포트 번호가 다르기에 CORS 에러가 발생합니다. 이때 프록시 서버를 둬서, 프론트엔드 서버에서 요청되는 오리진을 127.0.0.1:8080으로 바꾸는 일을 할 수 있습니다.
오리진이란?
- 프로토콜, 호스트 이름, 포트의 조합을 의미합니다. 예를 들어 https://ssoyeong.tistory.com:2023/test 라는 주소에서 오리진은 https://ssoyeong.tistoru.com:2023 을 뜻합니다.
CORS 에러란?
- Cross-Origin Resource Sharing
- CORS는 서버가 웹 브라우저에서 리소스를 로드할 때, 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘입니다.
- 즉, 서로 다른 오리진 간에 자원을 공유하는 것을 의미하며 기본적으로 브라우저에서는 현재 오리진과 다른 곳으로 요청을 보내는 것을 막아놓습니다.
7. MVC 패턴
MVC 패턴에 대해 설명해 주세요
- MVC 패턴은 모델(Model), 뷰(View), 컨트롤러(Controller)로 이루어진 디자인 패턴으로, 애플리케이션의 구성 요소를 세 가지로 구분해 가발 프로세스에서 각각의 구성 요소에만 집중해서 개발할 수 있습니다.
- 모델(Model)은 애플리케이션의 데이터인 데이터베이스, 상수, 변수 등을 뜻합니다. 뷰에서 데이터를 생성하거나 수정하면 컨트롤러를 통해 모델을 생성하거나 갱신합니다.
- 뷰(View)는 사용자 인터페이스 요소, 즉 모델을 기반으로 사용자가 볼 수 있는 화면을 뜻합니다. 변경이 일어나면 컨트롤러에 이를 전달해야 합니다.
- 컨트롤러(Controller)는 하나 이상의 모델과 하나 이상의 뷰를 잇는 다리 역할을 하며, 이벤트 등 메인 로직을 담당합니다. 또한 모델과 뷰의 생명주기를 관리하며, 모델이나 뷰의 변경사항에 대해 이를 해석해여 각각의 구성 요소에 해당 내용에 대해 알려줍니다.
- MVC 패턴은 재사용성과 확장성이 용이하다는 장점이 있으며, 애플리케이션이 복잡해질수록 모델과 뷰의 관계가 복잡해지는 단점이 있습니다.
MVC 패턴이 사용되는 예시를 들어주세요
- MVC 패턴을 이용한 대표적인 프레임워크로, 자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크인 Spring이 있습니다.
MVP 패턴에 대해 설명해 주세요
- MVP 패턴은 MVC 패턴으로부터 파생되었으며 MVC에서 C에 해당하는 컨트롤러가 프레젠터(Presenter)로 교체된 패턴입니다.
- 뷰와 프레젠터는 일대일 관계이기에 MVC 패턴보다 더 강한 결합을 지닌 디자인 패턴이라고 볼 수 있습니다.
MVVM 패턴에 대해 설명해 주세요
- MVVM 패턴은 MVC에서 C에 해당하는 컨트롤러가 뷰 모델(view model)로 교체된 패턴입니다.
- 뷰 모델은 뷰를 더 추상화한 계층이며, MVVM 패턴은 MVC 패턴과 다르게 커맨드와 데이터 바인딩을 가지는 것이 특징입니다. 뷰와 뷰 모델 사이의 양방향 데이터 바인딩을 지원하며, UI를 별도의 코드 수정 없이 재사용할 수 있고, 단위 테스팅하기 쉽다는 장점이 있습니다.
커맨드란?
- 여러 가지 요소에 대한 처리를 하나의 액션으로 처리할 수 있게 하는 기법입니다.
데이터 바인딩이란?
- 화면에 보이는 데이터와 웹 브라우저의 메모리 데이터를 일치시키는 기법으로, 뷰 모델을 변경하면 뷰가 변경됩니다.
MVVM 패턴이 사용되는 예시를 들어주세요
- MVVM 패턴을 가진 대표적인 프레임워크로 Vue.js가 있습니다. Vue.js는 반응형이 특징인 프론트엔드 프레임워크입니다.
- 함수를 사용하지 않고 값 대입만으로 변수가 변경되며 양방향 바인딩, html을 토대로 컴포넌트를 구축할 수 있다는 점이 특징입니다.
8. 이외
라이브러리와 프레임워크에 대해 설명해 주세요
- 라이브러리와 프레임워크는 특정한 기능들을 모듈화해 이미 완성된 코드를 재사용할 수 있도록 하여 개발 생산성을 향상시킨다는 공통적인 목적이 있습니다. 또한 표준화된 방법을 사용하면, 개발이 완료된 후에도 수정와 유지보수가 용이하다는 장점이 있습니다.
- 차이점은 제어의 흐름이 다르다는 것입니다. 라이브러리는 폴더명, 파일명 등에 대한 규칙이 없고 개발자가 주도적으로 라이브러리를 사용하는 시점을 결정합니다. 반면 프레임워크는 폴더명, 파일명 등에 대한 규칙이 있으며 프레임워크의 작동 방식에 맞추어 개발자가 자신의 코드를 수정해야 합니다.
자바의 상속과 구현에 대해 설명해 주세요
- 상속은 자식 클래스가 부모 클래스를, 자식 인터페이스가 부모 인터페이스를 상속받아 메소드 등을 재정의하여 기능을 추가 및 확장할 수 있는 것을 의미합니다.
- 구현은 부모 인터페이스를 자식 클래스에서 재정의하여 구현하는 것을 의미하며, 상속과 달리 반드시 부모의 메소드를 재정의해야 하기에 강제적으로 의존 관계를 만드는 용도로 사용됩니다.
어댑터 패턴에 대해 설명해 주세요
- 어댑터 패턴은 호환되지 않는 인터페이스를 가진 객체들이 협업할 수 있도록 하는 디자인 패턴입니다. 어댑터는 한 객체의 인터페이스를 다른 객체가 이해할 수 있도록 변환하는 객체입니다.
- 어댑터는 변환할 객체와 호환되는 인터페이스를 받고, 자기가 해야할 일을 클래스 멤버 객체의 메소드에게 다시 시킴으로서 목적을 달성합니다.
- 장점으로는, (아래의 설계 원칙)
- 단점으로는, 새로운 인터페이스와 어댑터 클래스를 도입해야 하기에 코드의 복잡성이 증가하며, 때로는 위임이 아닌 직접 클래스를 변경하는 것이 간단할 수 있기에 신중히 패턴을 적용해야 합니다.
어댑터 패턴과 관련된 설계 원칙에 대해 설명해 주세요
- 단일 책임 원칙, 프로그램의 기본 비즈니스 로직에서 인터페이스 또는 데이터 변환 코드를 분리할 수 있습니다.
- 개방 폐쇄 원칙, 클라이언트 코드가 클라이언트 인터페이스를 통해 어댑터와 작동하면, 기존의 클라이언트 코드를 손상시키지 않고 새로운 유형의 어댑터들을 프로그램에 도입할 수 있습니다.
어댑터 패턴이 사용되는 예시를 들어주세요
- 자바에서 콘솔로 입력을 받을 때, BufferedReader의 생성자 인자로 InputStreamReader 객체를 넣어 사용하는 경우가 있습니다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- input을 받는 System.in을 BufferedReader 객체를 통해 사용하고 싶은데, 중간에 InputStreamReader가 어댑터 역할을 하는 것입니다. System 클래스의 in 필드는 InputStream 타입으로 구성되어 있기에, 서로 타입이 맞지 않아 InputStreamReader를 어댑터로 사용해야 합니다.
https://refactoring.guru/ko/design-patterns
디자인 패턴들
refactoring.guru
'도서' 카테고리의 다른 글
[면접을 위한 CS 전공지식 노트] 2.4. IP 주소 (0) | 2023.08.18 |
---|---|
[면접을 위한 CS 전공지식 노트] 2.2. TCP와 UDP (0) | 2023.08.12 |
[면접을 위한 CS 전공지식 노트] 2.2. TCP/IP 4계층 모델 (0) | 2023.08.08 |