CS 지식노트 week 1-2 프록시, 이터레이터, 노출모듈, MV Pattern

froajnzd·2024년 10월 12일
0

cs note

목록 보기
2/2
post-thumbnail

프록시 패턴

대상 객체에 접근하기 전 그 접근에 대한 흐름을 가로채 해당 접근을 필터링하거나 수정하는 등의 역할을 하는 계층이 있는 패턴

쓰임

보안, 데이터 검증, 캐싱, 로깅에 사용

프록시 서버에서의 캐싱
캐시 안에 정보를 담아두고, 캐시 안에 있는 정보를 요구하는 요청에 대해 (멀리있는)원격 서버에 요청하지 않고 캐시 안에 있는 데이터를 활용하는 것.
=> 불필요하게 외부와 연결하지 않기에 트래픽을 줄일 수 있음

프록시 서버

서버와 클라이언트 사이에 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터시스템/응용프로그램

NGINX

비동기 이벤트 기반의 구조와 다수의 연결을 효과적으로 처리 가능한 웹서버
주로 Node.js 서버 앞단의 프록시 서버로 활용

CloudFlare

CDN 서비스 : 전세계적으로 분산된 서버 존재, 어떤 시스템의 콘텐츠 전달을 빠르게 할 수 있음

DDOS 공격 방어나 HTTPS 구축에 쓰임

서비스 배포 후 해외에서의 의심스러운 트래픽이 발생하면, 비용 저감을 위하여 CAPTCHA 등 기반으로 일정 부분 막음

인파님 블로그 보고 이해하기

이터레이터 패턴

iterator를 사용해 Collection의 요소들에 접근하는 패턴

순회 가능한 여러 자료형의 구조와 상관없이 이터레이터 인터페이스로 순회가 가능

장점

  1. 일관된 이터레이터 인터페이스를 사용해 여러 형태의 컬렉션에 대해 동일한 순회 방법을 제공한다.

  2. 컬렉션의 내부 구조 및 순회 방식을 알지 않아도 된다.

  3. 집합체의 구현과 접근하는 처리 부분을 반복자 객체로 분리해 결합도Visit Website를 줄 일 수 있다.

    • Client에서 iterator로 접근하기 때문에 ConcreteAggregate 내에 수정 사항이 생겨도 iterator에 문제가 없다면 문제가 발생하지 않는다.
  4. 순회 알고리즘을 별도의 반복자 객체에 추출하여 각 클래스의 책임을 분리하여 단일 책임 원칙(SRP)Visit Website를 준수한다.

  5. 데이터 저장 컬렉션 종류가 변경되어도 클라이언트 구현 코드는 손상되지 않아 수정에는 닫혀 있어 개방 폐쇄 원칙(OCP)Visit Website를 준수한다.

단점

  1. 클래스가 늘어나고 복잡도가 증가한다.

    • 만일 앱이 간단한 컬렉션에서만 작동하는 경우 패턴을 적용하는 것은 복잡도만 증가할 수 있다.
    • 이터레이터 객체를 만드는 것이 유용한 상황인지 판단할 필요가 있다.
  2. 구현 방법에 따라 캡슐화를 위배할 수 있다.

구조

  • Aggregate (인터페이스) : ConcreateIterator 객체를 반환하는 인터페이스를 제공한다.
    - iterator() : ConcreateIterator 객체를 만드는 팩토리 메서드
  • ConcreateAggregate (클래스) : 여러 요소들이 이루어져 있는 데이터 집합체
    - Iterator (인터페이스) : 집합체 내의 요소들을 순서대로 검색하기 위한 인터페이스를 제공한다.
    - hasNext() : 순회할 다음 요소가 있는지 확인 (true / false)
    - next() : 요소를 반환하고 다음 요소를 반환할 준비를 하기 위해 커서를 이동시킴
  • ConcreateIterator (클래스) : 반복자 객체
    - ConcreateAggregate가 구현한 메서드로부터 생성되며, ConcreateAggregate 의 컬렉션을 참조하여 순회한다.
    어떤 전략으로 순회할지에 대한 로직을 구체화 한다.
// 집합체 객체 (컬렉션)
interface Aggregate {
    Iterator iterator();
}

class ConcreteAggregate implements Aggregate {
    Object[] arr; // 데이터 집합 (컬렉션)
    int index = 0;

    public ConcreteAggregate(int size) {
        this.arr = new Object[size];
    }

    public void add(Object o) {
        if(index < arr.length) {
            arr[index] = o;
            index++;
        }
    }

    // 내부 컬렉션을 인자로 넣어 이터레이터 구현체를 클라이언트에 반환
    @Override
    public Iterator iterator() {
        return new ConcreteIterator(arr);
    }
}


// 반복체 객체
interface Iterator {
    boolean hasNext();
    Object next();
}

class ConcreteIterator implements Iterator {
    Object[] arr;
    private int nextIndex = 0; // 커서 (for문의 i 변수 역할)

    // 생성자로 순회할 컬렉션을 받아 필드에 참조 시킴
    public ConcreteIterator(Object[] arr) {
        this.arr = arr;
    }

    // 순회할 다음 요소가 있는지 true / false
    @Override
    public boolean hasNext() {
        return nextIndex < arr.length;
    }

    // 다음 요소를 반환하고 커서를 증가시켜 다음 요소를 바라보도록 한다.
    @Override
    public Object next() {
        return arr[nextIndex++];
    }
}


// 흐름
public static void main(String[] args) {
    // 1. 집합체 생성
    ConcreteAggregate aggregate = new ConcreteAggregate(5);
    aggregate.add(1);
    aggregate.add(2);
    aggregate.add(3);
    aggregate.add(4);
    aggregate.add(5);

    // 2. 집합체에서 이터레이터 객체 반환
    Iterator iter = aggregate.iterator();

    // 3. 이터레이터 내부 커서를 통해 순회
    while(iter.hasNext()) {
        System.out.printf("%s → ", iter.next());
    }
}

사용

컬렉션에 상관없이 객체 접근 순회 방식을 통일하고자 할 때
컬렉션을 순회하는 다양한 방법을 지원하고 싶을 때
컬렉션의 복잡한 내부 구조를 클라이언트로 부터 숨기고 싶은 경우 (편의 + 보안)
데이터 저장 컬렉션 종류가 변경 가능성이 있을 때

클라이언트가 집합 객체 내부 표현 방식을 알고 있다면, 표현 방식이 달라지면 클라이언트 코드도 변경되어야 하는 문제가 생긴다.

출처: https://inpa.tistory.com/entry/GOF-💠-반복자Iterator-패턴-완벽-마스터하기 [Inpa Dev 👨‍💻:티스토리]

노출모듈 패턴

즉시 실행 함수를 통해 private, public 같은 접근 제어자를 만드는 패턴
자바스크립트는 접근 제어자가 존재하지 않고 전역 범위에서 스크립트가 실행되기 때문에 노출모듈 패턴을 통해 private와 public 접근 제어자를 구현
→ 전역 범위에서 실행되는 프로그램은 내부 어플리케이션과 종속된 라이브러리 코드의 데이터들로 인해 충돌이 발생 할 수 있음.

장점

개발자에게 깔끔한 접근 방법을 제공
private 데이터 제공
전역 변수를 덜 더럽힘
클로저를 통해 함수와 변수를 지역화
스크립트 문법이 더 일관성 있음
명시적으로 public 메소드와 변수를 제공해 명시성을 높임

단점

private 메소드 접근할 방법이 없음 (그래서 테스트 불가란 얘기를 하는데 private은 테스트 할지 안할지 고민해봐야)
private 메소드에 대해 함수 확장하는데 어려움이 있음
private 메소드를 참조하는 public 메소드를 수정하기 어려움

구현

const module1 = (() => {
  const privateFoo = () => {};
  const privateBar = [];

  const exported = {
    publicFoo: () => {},
    publicBar: () => {},
  };

  return exported; //private 범위를 만들고 공개할 부분만 export 합니다.
})();

console.log(module1);
{ publicFoo : [Function: publicFoo],
  publicBar : [Function: publicBar] }

MVC 패턴


MVP 패턴

https://heegs.tistory.com/114

MVVM 패턴

profile
Hi I'm 열쯔엉

0개의 댓글