지나공 : 지식을 나누는 공간

[RxJava] 0. 리액티브 프로그래밍 + 마블다이어그램 본문

Tech/Reactive - Rxjava & Reactor

[RxJava] 0. 리액티브 프로그래밍 + 마블다이어그램

해리리_ 2022. 4. 7. 15:36

리액티브 프로그래밍(Reactive Programming)이란?

In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. 

변화의 전파데이터 흐름에 관련된 선언형 프로그래밍 패러다임이다.

 

 

wikipedia의 reactive programming 정의

  • 변화의 전파와 데이터 흐름 : 데이터가 변경될 때마다 이벤트를 발생시켜서 데이터를 계속적으로 전달한다.
  • 선언형 프로그래밍 : 실행할 동작을 구체적으로 명시하는 명령형 프로그래밍과 달리 목표만 선언한다.

 

 

명령형 프로그래밍 vs 선언형 프로그래밍

1. 명령형 프로그래밍

프로그래밍의 상태와 상태를 변경시키는 구문의 관점으로 접근하는 프로그래밍 방식. 컴퓨터가 실행할 명령들을 실행 순서대로 구현해야 한다. 대부분의 객체 지향 프로그래밍 언어가 명령형 프로그래밍 언어이고, 알고리즘 처리 작업에 적합한 언어다.

public int getPoint(Customer customer) {
    for (int i = 0; i < customers.size(); i++) {
        Customer c = customers.get(i);
        if (customer.equals(c)) {
            return c.getPoint();
        }
    }
    return NO_DATA;
}

/* 구체적인 동작을 정하는 방식
장난감 넣자. 뭐뭐 있니?
음~ 공이 있어.
그래 그럼 공 넣고. 또 뭐 있어?
인형 있어.
그래 그럼 인형 넣고, 또 뭐 있어?
책도 있어.
그래 그럼 책 넣고. 또 뭐 있어?
이제 끝이야 없어.
그래 그럼 끝내자.
*/

 

2. 선언현 프로그래밍

선언으로만 프로그램을 동작시킨다. 프로그램을 실행하기 위해 구체적인 작동 순서를 나열하지 않아도 된다. 완전하지 않지만 함수형 프로그래밍을 활용해 일정 수준의 선언형 프로그래밍을 할 수 있다. 함수형 프로그래밍은 선언형 프로그래밍의 한 종류라고 볼 수 있다.

public int getPoint(Customer customer) {
    if (isRegisteredCustomer(customer)) {
        return findCustomer(customer).getPoint();
    }
    return NO_DATA;
}
/*
구체적인 작동 순서 나열없이 선언을 해둠. 
나 이렇게 할거야.
*/

 

함수형 프로그래밍

함수가 1등시민이라서 함수를 함수의 인자로 받거나 함수의 반환 값으로 활용하는 것이 가능하다. 클린코드의 저자는 함수형 프로그래밍을 대입문이 없는 프로그래밍이라고 했다.

(참고로 함수형 인터페이스를 사용한다고 해서 함수형 프로그래밍인 건 아니다. 함수형 프로그래밍의 핵심은 순수함수여야 하는 것으로, 동일한 입력을 받았을 때 변경과 같은 사이드이펙 없이 항상 동일한 출력을 해야 하는 것이다. 함수형 인터페이스는 abstract 메소드가 하나인 인터페이스를 말하고 이런 경우 익명내부 클래스 -> 람다 변경 가능하고 @FunctionalInterface도 사용 가능하다.

MoveRule을 함수형인터페이스로 만들고 람다를 활용해서 간단하게 초기화할 수 있다.

 

마지막으로 한번 더 함수형 프로그래밍과 선언형 프로그래밍 예제 하나만 더 보자.

//명령형
List<Integer> numbers = Arrays.asList(1,2,3,4);
int sum = 0;

for(int number : numbers) {
	if(number > 6 && (number % 2 != 0)) {
    	sum += number;
    }
}

//선언형
List<Integer> numbers = Arrays.asList(1,2,3,4);
int sum = numbers.stream()
	.filter(numer -> number > 6 && (number % 2 != 0 ))
    .mapToInt(number -> number)
    .sum();

 

리액티브 개념이 적용된 예

앞서 리액티브는 변화의 전파로, 데이터가 변경될 때마다 이벤트를 발생시켜서 데이터를 계속적으로 전달한다고 했다.

  • push 방식: 데이터의 변화가 발생했을 때 변경이 발생된 곳에서 보내주는 방식
    • RTC(Real TIme Communition) 실시간 통신을 데이터를 직접 푸시해서 알려주는.
    • 소켓프로그래밍
    • Spring ApplicationEvent
    • 스마트폰 push 메시지
    • DB Trigger
    • 얘네 다 막 서버한테 변경된거 있냐고 묻는게 아니라 서버 측에서 변경이 발생하면 그때 알려주는 방식임.
  • pull 방식 : 변경된 데이터가 있는지 요청을 보내 질의하고 변경된 데이터를 가져오는 방식
    • 클라이언트 요청 & 서버 응답 방식의 애플리케이션
    • Java 같은 절차형 프로그래밍 언어

 

리액티브 프로그래밍에서 알아야 할 용어

  • Observable : 데이터 소스. 지속적으로 변경 가능한 데이터의 집합. 변경되는 데이터를 관찰할 수 있다.
  • 리액티브 연산자 : 데이터 소스를 처리하는, 가공하는 함수
  • 스케줄러 : 어떤 일정, 즉 스레드를 관리해. 리액티브 자체가 비동기 프로그래밍을 위한 기법이라서 스레드 관리자가 필요한데 그 관리자가 바로 스케줄러
  • Subscriber : Observable이 발행한 데이터를 구독하는 구독자야. 구독하지 않으면 Observable이 발행한 데이터를 전달받을 수 없어.
  • 함수형 프로그래밍 : 전통적으로는 여러 스레드가 동시에 실행되어서 개발자가 예상하지 못하는 문제가 자주 발생하고 그 문제를 재연하는 것조차 상당히 어려운 경우가 많았음. 이걸 해결하려고 사이드이펙이 없는 순수 함수를 지향하는 함수형 프로그래밍을 만들었고, 또 이런 기법으로 만들어진 함수가 리액티브 연산자야.

 

함수형 프로그래밍의 flow

리액티브는 기본적인 동작흐름을 기억해야 한다.

데이터를 발행(just)하고 처리 즉 가공(filter)하고 구독(subscribe)해서 결과를 받는다.

Observable.just(100,200,300,400)
	.filter(number -> number > 300)
    .subscribe(num -> System.out.println(getThreadName() + " : result :" + num));
Observable.just(100,200,300,400)
	.doOnNext(data -> System.out.println(getThreadName() + " : " + "doOnNext() : " + data))
	.subscribeOn(Schedulers.io())
    .observeOn(Schedulers.computation())
    .filter(number -> number > 300)
    .subscribe(num -> System.out.println(getThreadName() + " : result :" + num));
  • subscribeOn : 데이터의 발행, 흐름을 결정지을 스레드를 결정함.
  • obserOn : 발행된 데이터를 구독해서 처리할 스레드를 결정함

즉, 얘네 둘은 스케줄러 스레드를 결정하는 역할임.

 

RxJava를 간단히 사용해보자.

Observable을 통해 데이터를 생성하고 이 내용을 구독한 애가 데이터를 출력했다.

 

마블다이어그램이란?

리액티브 프로그래밍을 통해 발생하는 비동기적인 데이터의 흐름을 시간에 흐름에 따라 시각적으로 표현한 다이어그램.

 

이걸 왜 알아야 하냐,

1. 문장으로 적혀 있는 리액티브 연산자의 기능을 이해하기 어렵기 때문

2. 리액티브 연산자의 기능이 시각화되어 있어서 이해하기가 쉬우니까.

3. 리액티브 프로그래밍의 핵심임 연산자를 이해하는데에 도움을 준다!

 

 

마블다이어그램을 이해하자.

마블다이어그램 읽는 법

다음은 just 함수를 나타낸 마블 다이어그램이다.

이 함수는 별다른 가공처리 없이 저 값들을 파라미터로 받아서 이 데이터들을 통제하는 observable이나 flowable을 생성해주는 기능을 한다. 가공처리 없이 원본 데이터가 그대로 나온다. 눈으로 보면 단순히 데이터가 나온 것 같지만 just 함수는 이런 데이터를 통제하는 observable이나 flowable을 반환한다고 docs에 나와있다. 헷갈리지 말 것!

 

*Kevin의 알기 쉬운 RxJava를 정리한 내용입니다.

728x90
Comments