[CS 전공지식 노트] CH1 디자인패턴과 프로그래밍 패러다임

CH 1.1 디자인 패턴

SOLID (객체지향 설계 원칙) 디자인 원칙

(간략한 설명)

  1. Single Responsibility Principle하나의 클래스는 하나의 역할만 해야 함.
  2. Open - Close Principle확장 (상속)에는 열려있고, 수정에는 닫혀 있어야 함.
  3. Liskov Substitution Principle자식이 부모의 자리에 항상 교체될 수 있어야 함.
  4. Interface Segregation Principle인터페이스가 잘 분리되어서, 클래스가 꼭 필요한 인터페이스만 구현하도록 해야함.
  5. Dependency Inversion Property상위 모듈이 하위 모듈에 의존하면 안됨.
  6. 둘 다 추상화에 의존하며, 추상화는 세부 사항에 의존하면 안됨.

 

16 page

라이브러리 vs 프레임워크

프레임워크는 개발자가 개발을 쉽게 할 수 있도록 뼈대를 제공한다.
애플리케이션 개발 시 필수적인 코드, 알고리즘, DB 커넥션 등의 기능들을 위해 구조를 제공하고 개발자는 이런 구조 위에서 코드를 작성해 원하는 어플리케이션을 개발할 수 있다.

라이브러리는 주로 소프트웨어를 개발할 때 컴퓨터 프로그램이 사용하는 비휘발성 자원의 모음이다. 재사용이 가능한 기능을 미리 구현해두고 필요한 곳에서 호출하여 사용 가능하도록 만들어진 집합이다.

둘의 차이는?

프레임워크는 라이브러리를 포함한다. 프레임워크 위에 개발자가 작성한 애플리케이션 코드가 올라가고, 이 코드에서 라이브러리를 호출한다.
이러한 구조 때문에 개발자가 작성한 코드는 프레임워크에 의해 사용된다. 제어의 역전 개념이 적용되어 프레임워크에 제어 흐름을 넘기고 틀 안에서 수동적으로 동작한다.
반면 라이브러리는 이러한 제어의 흐름이 개발자에게 있다. 개발자에게 전적으로 제어 흐름이 있으며 능동적으로 라이브러리를 호출하여 사용한다.

React-Native 개발 시에 RN이라는 프레임워크 위에서 React-Native-Reanimated 같은 라이브러리를 설치하고 호출해서 사용했던 기억이 난다.

 

1.1.1 싱글톤 패턴

17 page

하나의 클래스에 오직 하나의 인스턴스만 가지는 것 -> 싱글톤 패턴을 적용한 자바 클래스에 대해  new를 통한 인스턴스화가 프로그램 내에서 단 한 번만 일어난다. 붕어빵 틀 한개로 단 하나의 붕어빵만 굽는다.

cf. 인스턴스: 일반적으로 어떤 집합에 대해서, 집합의 개별적인 요소. 객체지향프로그래밍에서 클래스에 소속된 개별적인 객체.
Class - 붕어빵틀, Object - 붕어빵, Instance - 각각의 붕어빵, 인스턴스화 하다 - 붕어빵을 굽다

'싱글톤은 하나의 인스턴스를 공유하는 것이다'라고 이해함.

싱글톤 장점, 쓰는 이유?

메모리 측면
최초 한번의 new 연산자를 통해 고정된 메모리 영역을 사용하므로 메모리 낭비를 방지하고, 이미 생성된 인스턴스를 활용하므로 속도 측면에서도 이점이 있다.
붕어빵 하나로 쓰니까 풀이랑 팥 아낄 수 있고 다시 구울 필요 없는 것

데이터 공유가 쉽다
전역으로 사용되는 인스턴스이므로 다른 클래스들의 인스턴스들이 접근하여 사용할 수 있다.

20 page

/*
1. 클래스안에 클래스(Holder), static이며 중첩된 클래스인 singleInstanceHolder를 
기반으로 객체를 선언했기 때문에 한 번만 로드되므로 싱글톤 클래스의 인스턴스는 애플리케이션 당 하나만 존재하며 
클래스가 두 번 로드되지 않기 때문에 두 스레드가 동일한 JVM에서 2개의 인스턴스를 생성할 수 없습니다. 
그렇기 때문에 동기화, 즉 synchronized를 신경쓰지 않아도 됩니다. 
2. final 키워드를 통해서 read only 즉, 다시 값이 할당되지 않도록 했습니다.
3. 중첩클래스 Holder로 만들었기 때문에 싱글톤 클래스가 로드될 때 클래스가 메모리에 로드되지 않고 
어떠한 모듈에서 getInstance()메서드가 호출할 때 싱글톤 객체를 최초로 생성 및 리턴하게 됩니다.
*/

 

23 page

cf.의존성: 파라미터나 리턴 값 또는 지역변수 등으로 다른 객체를 참조하는 것. 예를 들어 함수 a가 함수 b 안에서 쓰이면 b가 a에게 의존. 의존 대상 a가 변하면, 그게 b에 영향을 미치는 것.

cf. 의존성 주입: 의존 관계를 외부에서 결정하는 것, 
참고: 햄버거 레시피, 셰프와 사장 https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/

추가 문제점

(책에 없) 싱글톤 패턴을 구현하는 코드 자체가 많이 필요하다.

(책에 없) 테스트하기 어렵다. 자원을 공유하기 때문에 테스트가 결정적으로 격리된 환경에서 수행되려면 매번 인스턴스의 상태를 초기화시켜 주어야 한다. 

(책에 있음) 의존 관계상 클라이언트가 구체 클래스에 의존하게 된다. 

(싱글톤은 안티패턴으로 불릴 만큼 단독사용 시 객체지향에 위반되는 사례가 많다.)

 

1.1.2 팩토리 패턴

간단히 말해서 객체를 생성하는 클래스를 따로 두는 것.

팩토리 메서드 패턴과 추상 팩토리 패턴이 있다. 

 

 

1.1.3 전략패턴

 

 

 

1.1.4 옵저버 패턴

36 page

React 상태 관리 라이브러리인 MobX의 Observer가 생각남

40 page

프록시란?
"대리"의 의미로 특히 내부 네트워크에서 인터넷 접속을 할 때 빠른 액세스나 안전한 통신을 확보하기 위한 중계서버를 프록시 서버라고 한다.

JS에서의 Proxy 객체: 객체의 기본 동작을 가로채 특별한 다른 동작을 할 수 있게 함. 객체는 Object, Array, Dictionary 등 JS의 모든 자료형이 대상이 될 수 있다.

42 page

React 에서도 옵저버 패턴을 이용했다고 한다.
특히 상태관리 라이브러리에서 애플리케이션 상태를 관리하는데에 중요한 역할을 한다고 한다.

참고: https://studysection.com/blog/observer-pattern-in-react-reactjs/#:~:text=The%20observer%20pattern%20is%20used,of%20managing%20the%20application%20state.

 

Observer Pattern in React / ReactJS - StudySection Blog

The observer pattern is one of the most common patterns in software design. In this pattern, a subject contains a list of observers

studysection.com

 

 

1.1.5 프록시 패턴과 프록시 서버

44 page

프록시의 역할 자세하게

  1. 보안: 프록시는 클라이언트가 작업을 수행할 수 있는 권한이 있는지 확인하고 검사 결과가 긍정적인 경우에만 요청을 대상으로 전달한다.
  2. 캐싱: 프록시가 내부 캐시를 유지하여 데이터가 캐시에 아직 존재하지 않는 경우에만 대상에서 작업이 실행되도록 한다.
  3. 데이터 유효성 검사: 프록시가 입력을 대상으로 전달하기 전에 유효성을 검사한다.
  4. 지연 초기화: 대상의 생성 비용이 비싸다면 프록시는 그것이 필요할 때 까지 연기한다.
  5. 로깅: 프록시는 메소드 호출과 상대 매개 변수를 인터셉트하고 이를 기록한다.
  6. 원격 객체: 프록시는 원격 위치에 있는 객체를 가져와서 로컬처럼 보이게 할 수 있다.

 

프록시 서버

클라이언트 -> 서버로 접속 할 때 직접적으로 접속하지 않고 중간에 대신 전달해주는 서버를 의미한다. 
1. 클라이언트 -> 프록시 서버로 요청을 보낸다
2. 프록시 서버 -> 서버로 전달받은 요청을 요청한다.
3. 서버 -> 프록시 서버로 데이터를 전달한다.
4. 프록시 서버 -> 클라이언트로 서버로부터 전달받은 데이터를 클라이언트에 전달한다.

사용 이유

1. 보안: 가장 큰 이유. 사용 안하면 서버의 주소가 쉽게 노출되고 이를 통해 다른 익명 사용자가 서버로 접근하기 쉬워지게 된다. 
프록시 서버를 사용하면 서버의 IP를 숨길 수 있고 외부로부터의 위험을 막아준다.
2. 캐시: 이전에 했던 요청들을 프록시 서버에 저장해두어 다음에 클라이언트에서 요청받으면 서버 거치지 않고 데이터 주고 받을 수 있다. (빨라짐)
3. 우회: IP 주소를 감출 수 있기 때문에 어느 곳에서 접속한지를 숨길 수 있다. (해외 직구등 IP 변경 원리도 프록시 서버)

46 page

cf. CDN?
Content Delivery Network, 콘텐츠 전송 네트워크는 지리적 제약 없이 전 세계 사용자에게 빠르게 안전하게 콘텐츠를 전송할 수 있는 전송 기술. 서버-클라이언트 사이의 물리적인 거리를 줄여 콘텐츠 로딩 시간을 최소화함. 각 지역에 캐시 서버를 두어 캐시 서버가 콘텐츠를 전달한다. eg) Netflix

 

1.1.6 이터레이터 패턴

 

1.1.7 노출 모듈 패턴

51 page

자바스크립트는 provate, public 등의 접근 제어자가 없고 전역에서 스크립트가 실행된다. 따라서 노출모듈 패턴을 통해 접근 제어자를 구현한다.

cf. 오픈범위: public > protected > private

자바스크립트에서는 클로저를 사용해 현재 상태를 기억하고 변경된 최신 상태를 유지할 수 있다.

const pukuba = (() => {
    const a = 1
    const b = () => 2
    const public = {
        c : 2, 
        d : () => 3
    }
    return public 
})() 
console.log(pukuba)
console.log(pukuba.a)
// { c: 2, d: [Function: d] }
// undefined

위 코드에서 함수 pukuba는 내부함수 public을 리턴함으로써 함수 public은 pukuba 외부에서 호출될 때 pukuba의 내부 콘텍스트를 참조할 수 있다.
변수 a와 함수 b는 그럴 수 없다. 
이러한 클로저의 특성을 이용해 마치 Java의 private, public 접근제어자처럼 사용할 수 있다.

cf. 즉시 실행 함수
함수 표현 (Function Expression)은 함수를 정의하고, 변수에 함수를 저장하고 실행하는 과정을 거치지만, 즉시 실행함수는 함수를 정의하고 바로 실행함. 함수를 정의하자마자 바로 호출함.

(function square(x) {          // 가명 즉시실행 함수
  console.log(x*x);
})(2);

(function (x) {          // 익명 즉시실행 함수
  console.log(x*x);
})(2);

 

1.1.8 MVC 패턴

 

 

1.1.9 MVP 패턴

 

 

1.1.10 MVVM 패턴

 

1.2 프로그래밍 패러다임

 

1.2.1

 

 

1.2.2 객체 지향 프로그래밍

63 page

리스코프 치환 원칙: 부모 클래스의 인스턴스를 사용하는 위치에 자식 클래스의 인스턴스를 대신 사용했을 때 코드가 원래 의도대로 작동해야 한다는 의미이다.

 

 

1.2.3

 

 

 

빈도 높은 인터뷰 질문들

1. 싱글톤 패턴이란?

2. 솔리드 개발 원칙이란?

3. 프레임워크와 라이브러리의 차이

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

5. 오버로딩과 오버라이딩의 차이?

 

 

GoF(Gang of Fout, 디자인 패턴을 구체화하고 체계화한 사람들)이 세가지로 분류한 디자인 패턴.

생성 패턴 (Creational) 구조 패턴 (Structual) 행위 패턴 (Behavioral)
1.1.1 싱글톤 패턴
1.1.2 추상 팩토리/팩토리 메서드 패턴
1.1.5 프록시 패턴 1.1.3 전략 패턴
1.1.4 옵저버 패턴
1.1.6 이터레이터 패턴
cf. 템플릿 메서드 패턴
  • 생성(Creational) 패턴
    • 객체 생성에 관련된 패턴
    • 객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을 제공한다.
  • 구조(Structural) 패턴
    • 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴
    • 예를 들어 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스를 제공하거나 객체들을 서로 묶어 새로운 기능을 제공하는 패턴이다.
  • 행위(Behavioral)
    • 객체나 클래스 사이의 알고리즘이나 책임 분배에 관련된 패턴
    • 한 객체가 혼자 수행할 수 없는 작업을 여러 개의 객체로 어떻게 분배하는지, 또 그렇게 하면서도 객체 사이의 결합도를 최소화하는 것에 중점을 둔다.

출처: https://gmlwjd9405.github.io/2018/07/06/design-pattern.html

 

[Design Pattern] 디자인 패턴 종류 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

Q. 1.1.7-10 패턴은 어디에 들어갈까?