반응형 프로그래밍 자바. FRP: 함수형 리액티브 프로그래밍(Functional Reactive Programming). ReactiveCocoa의 주요 구성 요소




시간이 지남에 따라 프로그래밍 언어는 새로운 기술, 최신 요구 사항 또는 코딩 스타일을 새로 고치려는 단순한 욕구로 인해 끊임없이 변화하고 발전합니다. Reactive Cocoa와 같은 다양한 프레임워크를 사용하여 Reactive 프로그래밍을 구현할 수 있습니다. 이는 Objective-C 언어의 명령형 스타일을 변경하며 프로그래밍에 대한 이러한 접근 방식은 표준 패러다임에 제공할 무언가를 제공합니다. 물론 이는 iOS 개발자들의 관심을 끌고 있습니다.

ReactiveCocoa는 Objective-C에 선언적 스타일을 제공합니다. 이것이 무엇을 의미합니까? C, C++, Objective-C, Java 등과 같은 언어에서 사용되는 전통적인 명령형 스타일은 다음과 같이 설명할 수 있습니다. 특정 방식으로 실행되어야 하는 컴퓨터 프로그램에 대한 지시문을 작성합니다. . 즉, 무언가를 "어떻게 해야 하는가"라고 말하는 것입니다. 선언적 프로그래밍을 사용하면 "어떻게 할지"를 정의하지 않고도 "무엇을 할지"라는 일련의 작업으로 제어 흐름을 설명할 수 있습니다.

명령형 프로그래밍과 함수형 프로그래밍

프로그래밍에 대한 명령형 접근 방식에는 컴퓨터가 작업을 완료하기 위해 수행해야 하는 각 단계를 자세히 설명하는 것이 포함됩니다. 실제로 명령형 스타일은 네이티브 프로그래밍 언어에서 사용됩니다(또는 기계어 코드를 작성할 때 사용됩니다). 그건 그렇고, 이것은 대부분의 프로그래밍 언어의 특징입니다.

대조적으로, 기능적 접근 방식은 수행해야 하는 일련의 기능을 사용하여 문제를 해결합니다. 각 함수에 대한 입력 매개변수와 각 함수가 반환하는 내용을 정의합니다. 이 두 가지 프로그래밍 접근 방식은 매우 다릅니다.

언어 간의 주요 차이점은 다음과 같습니다.

1. 상태 변화

순수 함수형 프로그래밍의 경우 부작용이 없기 때문에 상태 변경이 존재하지 않습니다. 부작용에는 일부 외부 상호 작용으로 인한 반환 값 외에도 상태 변경이 포함됩니다. 하위 표현식의 RP(참조 투명성)는 종종 "부작용 없음"으로 정의되며 주로 순수 기능과 관련됩니다. SP는 함수 실행이 함수의 휘발성 상태에 대한 외부 액세스를 허용하지 않습니다. 왜냐하면 모든 하위 표현식은 정의에 따른 함수 호출이기 때문입니다.

요점을 명확히 하기 위해 순수 함수에는 다음과 같은 속성이 있습니다.

  • 유일하게 눈에 띄는 출력은 반환 값입니다.
  • 입력 매개변수의 유일한 종속성은 인수입니다.
  • 출력이 생성되기 전에 인수가 완전히 지정됩니다.

기능적 접근 방식이 부작용을 최소화한다는 사실에도 불구하고 부작용은 모든 개발에 내재된 부분이기 때문에 완전히 피할 수는 없습니다.

반면에 명령형 프로그래밍의 함수에는 참조 투명성이 없으며 이것이 선언적 접근 방식과 명령형 접근 방식의 유일한 차이점일 수 있습니다. 부작용은 상태 및 I/O를 구현하는 데 널리 사용됩니다. 소스 언어의 명령은 상태를 변경하여 동일한 언어 표현에 대해 다른 값을 생성할 수 있습니다.

ReactiveCocoa는 어떻습니까? 이는 순수 함수를 명시적으로 포함하지 않고 개념적으로 명령형 언어인 Objective-C를 위한 함수형 프레임워크입니다. 상태 변화를 피하려고 할 때 부작용에는 제한이 없습니다.

2. 최고급 시설

함수형 프로그래밍에는 일급 객체인 객체와 함수가 있습니다. 무슨 뜻이에요? 즉, 함수를 매개변수로 전달하거나, 변수에 할당하거나, 함수에서 반환할 수 있습니다. 이것이 왜 편리한가요? 이를 통해 실행 블록을 쉽게 관리하고, 함수 포인터(char *(*(**foo)()); - 재미있게 보내세요!)와 같은 복잡함 없이 다양한 방법으로 함수를 생성 및 결합할 수 있습니다.

명령형 접근 방식을 사용하는 언어는 일급 표현에 있어서 고유한 특성을 가지고 있습니다. Objective-C는 어떻습니까? 클로저 구현으로 블록이 있습니다. 고차 함수(HOF)는 블록을 매개변수로 사용하여 모델링할 수 있습니다. 이 경우 블록은 클로저이며 특정 블록 세트에서 고차 함수를 생성할 수 있습니다.

그러나 함수형 언어에서 FVP를 조작하는 프로세스는 더 빠르고 더 적은 코드 라인이 필요합니다.

3. 주요 흐름 제어

명령형 루프는 함수형 프로그래밍에서 재귀 함수 호출로 표현됩니다. 함수형 언어의 반복은 일반적으로 재귀를 통해 수행됩니다. 왜? 아마도 복잡성 때문일 것입니다. Objective-C 개발자에게는 루프가 훨씬 프로그래머 친화적인 것처럼 보입니다. 재귀는 과도한 RAM 소비와 같은 문제를 일으킬 수 있습니다.

하지만! 루프나 재귀를 사용하지 않고도 함수를 작성할 수 있습니다. 컬렉션의 각 요소에 적용할 수 있는 무한히 가능한 각 특수 작업에 대해 함수형 프로그래밍은 다음과 같은 재사용 가능한 반복 함수를 사용합니다. 지도”, “”, “" 이러한 함수는 소스 코드를 리팩토링하는 데 유용합니다. 중복을 줄이고 별도의 함수를 작성할 필요가 없습니다. (계속 읽어보세요. 이에 대한 자세한 정보가 있습니다!)

4. 집행순서

선언적 표현식은 하위 표현식 함수의 인수와 상수 상태 관계 간의 논리적 관계만 표시합니다. 따라서 부작용이 없는 경우 각 함수 호출의 상태 전환은 다른 함수 호출과 독립적으로 발생합니다.

명령형 실행의 기능적 순서는 비지속적 상태에 따라 달라집니다. 따라서 실행 순서가 중요하며 소스 코드 구성에 따라 암시적으로 결정됩니다. 이 문제에서 우리는 두 접근 방식의 평가 전략의 차이점을 지적할 수 있습니다.

지연 평가 또는 주문형 평가는 함수형 프로그래밍 언어의 전략입니다. 이 경우 해당 값이 필요할 때까지 표현식 평가가 지연되므로 반복 평가가 방지됩니다. 즉, 표현식은 종속 표현식이 평가될 때만 평가됩니다. 작업 순서가 불확실해집니다.

대조적으로, 명령형 언어에서 활발한 평가는 표현식이 변수에 바인딩되자마자 평가된다는 것을 의미합니다. 이는 실행 순서를 지정함을 의미합니다. 따라서 하위 표현식(함수 포함)이 평가되는 시점을 결정하는 것이 더 쉽습니다. 하위 표현식에는 다른 표현식의 평가에 영향을 미치는 부작용이 있을 수 있기 때문입니다.

5. 코드 개수

이는 중요합니다. 기능적 접근 방식은 명령형 접근 방식보다 적은 코드를 작성해야 합니다. 이는 충돌이 적고 테스트할 코드가 적으며 개발 주기가 더욱 생산적이라는 것을 의미합니다. 시스템은 지속적으로 발전하고 성장하기 때문에 이것이 중요합니다.

ReactiveCocoa의 주요 구성 요소

함수형 프로그래밍은 future(변수의 읽기 전용 표현)와 promise(변수 future의 읽기 전용 표현)라는 개념을 사용하여 작동합니다. 그들의 좋은 점은 무엇입니까? 명령형 프로그래밍에서는 기존 값을 사용하여 작업해야 하므로 비동기 코드를 동기화해야 하며 기타 어려움이 있습니다. 그러나 미래와 약속의 개념을 사용하면 아직 생성되지 않은 값으로 작업할 수 있습니다(비동기 코드는 동기 방식으로 작성됨).


신호

미래와 약속은 반응형 프로그래밍에서 신호로 표현됩니다. -ReactiveCocoa의 주요 구성 요소입니다. 앞으로 펼쳐질 사건의 흐름을 짐작할 수 있게 해준다. 신호를 구독하고 시간이 지남에 따라 발생하는 이벤트에 액세스할 수 있습니다. 신호는 푸시 기반 흐름이며 버튼 클릭, 비동기 네트워크 작업, 타이머, 기타 UI 이벤트 또는 시간에 따라 변경되는 모든 것을 나타낼 수 있습니다. 비동기 작업의 결과를 바인딩하고 여러 이벤트 소스를 효율적으로 결합할 수 있습니다.

후속 시퀀스

또 다른 유형의 흐름은 시퀀스입니다. 신호와 달리 시퀀스는 풀 기반 흐름입니다. 이는 NSArray와 비슷한 목적을 가진 일종의 컬렉션입니다. RACSequence를 사용하면 컬렉션처럼 순차적으로 수행하는 대신 필요할 때 특정 작업을 수행할 수 있습니다. NSArray. 시퀀스의 값은 기본적으로 지정된 경우에만 평가됩니다. 시퀀스의 일부만 사용하면 잠재적으로 성능이 향상됩니다. RAC시퀀스 Cocoa 컬렉션을 일반적이고 선언적인 방식으로 처리할 수 있습니다. RAC는 대부분의 Cocoa 컬렉션 클래스에 -rac_sequence 메소드를 추가하여 다음과 같이 사용할 수 있습니다. RAC시퀀스.

특정 작업에 대한 응답으로 생성됨 RACC 명령신호를 구독합니다. 이는 주로 UI 상호 작용에 적용됩니다. 카테고리 UIKit대부분의 컨트롤에 대해 ReactiveCocoa에서 제공 UIKit, UI 이벤트를 처리하는 올바른 방법을 알려주십시오. 버튼 클릭에 대한 응답으로 사용자를 등록해야 한다고 가정해 보겠습니다. 이 경우 명령은 네트워크 요청을 나타낼 수 있습니다. 프로세스가 실행되기 시작하면 버튼 상태가 "비활성"으로 변경되고 그 반대의 경우도 마찬가지입니다. 또 뭐야? 명령에서 활성 신호를 전달할 수 있습니다(Reachable이 좋은 예입니다). 따라서 서버를 사용할 수 없는 경우("신호 중") 명령을 사용할 수 없으며 관련 컨트롤의 각 명령에 이 상태가 반영됩니다.

기본 작업의 예

다음은 RACSignals의 기본 작동 방식에 대한 몇 가지 다이어그램입니다.

병합

+ (RACSignal *)병합:(id ) 신호;


결과 스트림에는 두 이벤트 스트림이 함께 결합되어 있습니다. 따라서 "+병합"은 특정 이벤트 소스에 관심이 없지만 한 곳에서 처리하고 싶을 때 유용합니다. 이 예에서 stateLabel.text는 진행률, 완료, 오류라는 3가지 신호를 사용합니다.

RACCommand *loginCommand = [ initWithSignalBlock:^RACSignal *(id input) ( // 로그인하자! )]; RACSignal *executionSignal = ; RACSignal *completionSignal = filter:^BOOL(RACEvent *event) ( return event.eventType == RACEventTypeCompleted; )] map:^id(id value) ( ​​​​return @"Done"; )];

+ (RACSignal *)combine최신:(id ) 신호 감소:(id (^)())reduceBlock;

결과적으로 스트림에는 전송된 스트림의 최신 값이 포함됩니다. 스트림 중 하나에 값이 없으면 결과는 비어 있습니다.


언제 사용할 수 있나요? 이전 예제에 로직을 더 추가해 보겠습니다. 사용자가 올바른 이메일과 비밀번호를 입력한 경우에만 로그인 버튼을 활성화하는 것이 유용합니다. 그렇죠? 이 규칙을 다음과 같이 선언할 수 있습니다.

ACSignal *enabledSignal = 감소:^id (NSString *email, NSString *password) ( return @( && 비밀번호.길이 > 3); )];

*이제 로그인 명령을 약간 변경하여 실제 loginButton에 연결해 보겠습니다.

RACCommand *loginCommand = [ initWithEnabled:enabledSignal signalBlock:^RACSignal *(id input) ( // 로그인합시다! )];

- (RACSignal *) flattenMap:(RACStream * (^)(id value))block;

주어진 함수(f)를 사용하여 원래 스트림의 각 값에 대해 새 스트림을 생성합니다. 결과 스트림은 원래 스트림에서 생성된 값을 기반으로 새로운 신호를 반환합니다. 따라서 비동기식일 수 있습니다.


시스템에 대한 인증 요청이 Facebook에서 데이터(식별자 등)를 수신하고 이를 백엔드로 전달하는 두 가지 개별 부분으로 구성되어 있다고 가정해 보겠습니다. 요구 사항 중 하나는 로그인을 취소할 수 있어야 한다는 것입니다. 따라서 클라이언트 코드는 로그인 프로세스를 취소할 수 있도록 상태를 처리해야 합니다. 이로 인해 특히 여러 위치에서 로그인할 수 있는 경우 상용구 코드가 많이 생성됩니다.

ReactiveCocoa는 어떻게 도움이 되나요? 이는 로그인 구현일 수 있습니다.

- (RACSignal *)authorizeUsingFacebook ( return [[ flattenMap:^RACStream *(FBSession *session) ( return ; )] flattenMap:^RACStream *(NSDictionary *profile) ( return ; )]; )

전설:

+ - 오프닝으로 이어지는 신호 FBSession. 필요한 경우 진입으로 이어질 수 있습니다. 페이스북.

- - 세션을 통해 프로필 데이터를 검색하는 신호로 전송됩니다. 본인.

이 접근 방식의 장점은 사용자의 경우 전체 흐름이 Facebook 로그인이든 백엔드 호출이든 모든 "단계"에서 취소될 수 있는 단일 신호로 표시된다는 점입니다.

필터

- (RACSignal *)filter:(BOOL (^)(id 값))block;

결과 스트림에는 지정된 함수에 따라 필터링된 스트림 "a"의 값이 포함됩니다.


RACSequence *sequence = @[@"Some", @"example", @"of", @"sequence"].rac_sequence; RACSequence *filteredSequence = ; )];

지도

- (RACSignal *)map:(id (^)(id 값))block;

FlattenMap과 달리 Map은 동기적으로 실행됩니다. 속성 "a"의 값은 주어진 함수 f(x + 1)를 통해 전달되고 매핑된 원래 값을 반환합니다.


화면에 모델의 제목을 입력하고 일부 속성을 적용해야 한다고 가정해 보겠습니다. "일부 속성 적용"이 별도의 기능으로 설명될 때 맵이 작동합니다.

RAC(self.titleLabel, text) = initWithString:modelTitle 속성:속성]; )];

우리가 일하는 방식: 단결하다 self.titleLabel.text변화가 있는 모델.제목사용자 정의 속성을 적용하여

지퍼

+ (RACSignal *)zip:(id ) 스트림 감소:(id (^)())reduceBlock;

결과 스트림 이벤트는 각 스레드가 동일한 수의 이벤트를 생성할 때 생성됩니다. 여기에는 병합된 3개의 스트림 각각에서 하나씩 값이 포함됩니다.


몇 가지 실제적인 예를 들어 zip은 다음과 같이 설명할 수 있습니다. 파견_그룹_통지예를 들어 3개의 개별 신호가 있고 해당 신호의 응답을 단일 지점에서 결합해야 합니다.

NSArray *신호 = @; 반품 ;

- (RACSignal *) 스로틀:(NSTimeInterval) 간격;

일정 시간 동안 설정된 타이머를 사용하면 타이머가 종료될 때만 스트림 "a"의 첫 번째 값이 결과 스트림으로 전송됩니다. 주어진 시간 간격 내에 새 값이 생성되는 경우 첫 번째 값을 보유하여 결과 스트림으로 전달되는 것을 방지합니다. 대신 결과 스트림에 두 번째 값이 나타납니다.


놀라운 사례: 사용자가 searchField를 변경할 때 쿼리를 검색해야 합니다. 표준 작업 맞죠? 그러나 textField는 초당 그러한 이벤트를 많이 생성할 수 있고 결국 비효율적인 네트워크 사용으로 끝나기 때문에 텍스트가 변경될 때마다 네트워크 요청을 구성하고 보내는 것은 그리 효율적이지 않습니다.
여기서 해결책은 실제로 네트워크 요청을 완료하기 전에 지연을 추가하는 것입니다. 이는 일반적으로 NSTimer를 추가하여 수행됩니다. ReactiveCocoa를 사용하면 훨씬 쉬워집니다!

[[ throttle:0.3] subscribeNext:^(NSString *text) ( // 네트워크 요청 수행 )];

*여기서 중요한 점은 "최신" 텍스트 필드가 삭제되기 전에 모든 "이전" 텍스트 필드가 변경된다는 것입니다.

지연

- (RACSignal *)지연:(NSTimeInterval)간격;

스트림 "a"에 수신된 값은 일정 시간 간격 후에 지연되어 결과 스트림으로 전송됩니다.


-와 마찬가지로 지연은 "다음" 및 "완료" 이벤트 전송만 지연시킵니다.

[ subscribeNext:^(NSString *text) ( )];

Reactive Cocoa의 장점

  • iOS에 Cocoa 바인딩 도입
  • 미래 데이터에 대한 작업을 생성하는 능력. 다음은 Scala의 미래 및 약속에 관한 몇 가지 이론입니다.
  • 비동기 작업을 동기 방식으로 표현하는 기능. Reactive Cocoa는 네트워크 코드와 같은 비동기 소프트웨어를 단순화합니다.
  • 편리한 분해. 사용자 이벤트 및 애플리케이션 상태 변경을 처리하는 코드는 매우 복잡하고 혼란스러울 수 있습니다. Reactive Cocoa는 종속 작업 모델을 특히 간단하게 만듭니다. 작업을 번들 스레드(예: 네트워크 요청, 사용자 이벤트 처리 등)로 표현하면 높은 모듈성과 느슨한 결합을 달성할 수 있어 코드 재사용이 더 자주 발생합니다.
  • 속성 간의 동작과 관계는 선언적으로 정의됩니다.
  • 동기화 문제 해결 - 여러 신호를 결합하면 모든 결과(다음 값, 완료 신호 또는 오류 등)를 한 곳에서 처리할 수 있습니다.

RAC 프레임워크를 사용하면 더 나은, 더 높은 수준의 방식으로 값 시퀀스를 생성하고 변환할 수 있습니다. RAC를 사용하면 비동기 작업이 완료되기를 기다리는 모든 것(네트워크 응답, 종속 값 변경, 후속 응답)을 더 쉽게 관리할 수 있습니다. 처음에는 대처하기 어려워 보일 수도 있지만 ReactiveCocoa는 전염성이 있습니다!

정보를 확인하세요. 본 기사에 게재된 정보의 사실관계와 신빙성을 확인해 볼 필요가 있습니다. 토론 페이지에 설명이 있어야 하는데... 위키피디아

상호작용성은 객체 간 상호작용의 성격과 정도를 나타내는 개념이다. 정보 이론, 컴퓨터 과학 및 프로그래밍, 통신 시스템, 사회학, 산업 디자인 등의 분야에서 사용됩니다. 에서... ... 위키피디아

이 글은 위키화되어야 합니다. 기사 형식 규칙에 따라 형식을 지정해 주세요. 이 용어에는 다른 의미가 있습니다. Elektromash (의미) ... Wikipedia를 참조하세요.

외국의 심리치료 기술- 심층 기술 적극적 심리치료(Fromm Reichmann). 존재 분석(Binswanger). 운명 분석(Sondi). 캐릭터 분석 (W. Reich). 자기 분석(H. Kohut, E. Erikson). 분석적 놀이치료(M. Klein). 분석적 가족치료(리히터).… 훌륭한 심리학 백과사전

서적

  • C++의 반응형 프로그래밍. Pai Prasidh, Abraham Peter를 사용하여 병렬 및 비동기 애플리케이션 설계. RxCpp 라이브러리와 언어 표준 Collaborative에서 지원하는 최신 C++17 병렬 프로그래밍 도구를 사용하여 병렬 및 비동기 애플리케이션 설계…
  • , Nurkiewicz T., Christensen B.. 프로그램이 비동기적이고 빠른 응답이 가장 중요한 속성인 요즘에는 리액티브 프로그래밍을 사용하여 보다 안정적이고 확장 가능하며 빠르게 실행되는 코드를 작성할 수 있습니다.…
  • RxJava를 사용한 반응형 프로그래밍, Nurkiewicz Tomasz, Christensen Ben. 프로그램이 비동기적이고 응답성이 가장 중요한 시대에 반응형 프로그래밍은 보다 안정적이고 확장 가능하며 더 빠르게 실행되는 코드를 작성하는 데 도움이 될 수 있습니다.…

일반적으로 OOP 개발 세계, 특히 Java 언어는 매우 활동적인 삶을 살고 있습니다. 여기에는 패션 트렌드가 있으며 오늘은 이번 시즌의 주요 트렌드 중 하나인 ReactiveX 프레임워크를 살펴보겠습니다. 아직 이 물결에 대해 고민 중이시라면, 마음에 드실 거라고 약속드립니다! 확실히 하이웨이스트 청바지보다 더 예뻐요 :)

반응형 프로그래밍

OOP 언어가 대량 채택되자마자 개발자들은 C와 유사한 언어의 기능이 얼마나 부족한지 깨달았습니다. 함수형 프로그래밍 스타일로 코드를 작성하면 OOP 코드의 품질이 심각하게 손상되어 프로젝트의 유지 관리성이 저하되므로 하이브리드가 발명되었습니다. 반응형 프로그래밍.

반응형 개발 패러다임은 객체 상태의 변화를 지속적으로 모니터링한다는 아이디어를 기반으로 합니다. 그러한 변경이 발생한 경우 관심 있는 모든 객체는 업데이트된 데이터를 수신하고 이전 데이터는 잊어버리고 해당 데이터로만 작업해야 합니다.

반응형 프로그래밍 아이디어의 좋은 예는 Excel 스프레드시트입니다. 여러 셀을 하나의 수식으로 연결하면 해당 셀의 데이터가 변경될 때마다 계산 결과가 변경됩니다. 회계의 경우 데이터의 이러한 동적 변경은 흔한 일이지만 프로그래머에게는 이는 예외입니다.

A=3; b=4; c=a + b; F1(c); a=1; F2(c);

이 예에서 함수 F1과 F2는 변수 C의 서로 다른 값으로 작동합니다. 두 함수 모두 최신 데이터만 가져야 하는 경우가 많습니다. 반응형 프로그래밍을 사용하면 논리를 변경하지 않고 새 매개변수로 F1을 즉시 호출할 수 있습니다. 기능 자체의. 이 코드 구조는 애플리케이션이 모든 변경 사항에 즉시 응답할 수 있는 기능을 제공하므로 빠르고 유연하며 응답성이 뛰어납니다.

리액티브X

반응형 프로그래밍 아이디어를 처음부터 구현하는 것은 꽤 번거로울 수 있습니다. 함정이 있고 시간이 많이 걸릴 것입니다. 따라서 많은 개발자들에게 이 패러다임은 ReactiveX가 등장할 때까지 단지 이론적인 자료로만 남아 있었습니다.

ReactiveX 프레임워크는 널리 사용되는 모든 OOP 언어에서 작동하는 반응형 프로그래밍 도구입니다. 제작자는 이를 Observer 패턴을 기반으로 하는 비동기 개발을 위한 다중 플랫폼 API라고 부릅니다.

"반응형 프로그래밍"이라는 용어가 일종의 이론적 모델이라면 "관찰자" 패턴은 프로그램의 변경 사항을 추적하기 위해 미리 만들어진 메커니즘입니다. 그리고 데이터 다운로드 및 업데이트, 이벤트 알림 등을 매우 자주 추적해야 합니다.

Observer 패턴은 OOP 자체만큼이나 오랫동안 사용되어 왔습니다. 상태가 변경될 수 있는 객체를 게시자(Observable이라는 용어의 대중적인 번역)라고 합니다. 이러한 변화에 관심이 있는 다른 모든 참가자는 구독자(관찰자, 구독자)입니다. 알림을 받으려면 구독자는 자신의 ID를 명시적으로 제공하여 게시자에 등록합니다. 게시자는 때때로 등록된 구독자 목록에 전송되는 알림을 생성합니다.

실제로 ReactiveX의 개발자들은 혁신적인 것을 생각해낸 것이 아니라 단지 패턴을 편리하게 구현했을 뿐입니다. 많은 OOP 언어, 특히 Java에는 기성 패턴 구현이 있지만 이 프레임워크에는 Observer를 매우 강력한 도구로 바꾸는 추가 "조정"이 포함되어 있습니다.

Rx안드로이드

Android용 ReactiveX 라이브러리 포트는 rxAndroid라고 하며 항상 그렇듯이 Gradle을 통해 연결됩니다.

"io.reactivex:rxandroid:1.1.0" 컴파일

알림을 생성하는 게시자는 여기에서 Observable 클래스를 사용하여 지정됩니다. 게시자는 이를 구현하기 위해 여러 구독자를 가질 수 있으며 구독자 클래스를 사용합니다. Observable의 표준 동작은 구독자에게 하나 이상의 메시지를 발행한 다음 종료하거나 오류 메시지를 발행하는 것입니다. 메시지는 변수일 수도 있고 전체 객체일 수도 있습니다.

Rx.Observable myObserv = rx.Observable.create(새 rx.Observable.OnSubscribe () ( @Override 공개 무효 통화(구독자구독자) ( subscriber.onNext("Hello"); subscriber.onNext("world"); subscriber.onCompleted(); ) ));

이 경우 myObserv 게시자는 먼저 hello 및 message 문자열을 보낸 다음 성공 메시지를 보냅니다. 게시자는 onNext() , onCompleted() 및 onEror() 메서드를 호출할 수 있으므로 구독자는 해당 메서드를 정의해야 합니다.

구독자 mySub = 신규 구독자 () (... @Override public void onNext(String value) (Log.e("got data", " " + value);) );

모든 것이 준비되었습니다. 남은 것은 개체를 서로 연결하고 "Hello, world!"하는 것뿐입니다. 반응형 프로그래밍을 위한 준비!

MyObserv.subscribe(mySub);

나는 이것이 매우 간단한 예라고 말해야합니다. ReactiveX에는 필터링, 그룹화, 오류 처리 등 모든 패턴 참여자의 동작에 대한 다양한 옵션이 있습니다. 리액티브 프로그래밍의 이점은 실제로 시도해 볼 때만 느낄 수 있습니다. 좀 더 심각한 작업으로 넘어 갑시다.

계속 이용은 회원만 가능합니다

옵션 1. "사이트" 커뮤니티에 가입하여 사이트의 모든 자료를 읽으세요.

지정된 기간 내에 커뮤니티에 가입하면 모든 Hacker 자료에 액세스할 수 있고 개인 누적 할인이 증가하며 전문적인 Xakep 점수 등급을 누적할 수 있습니다!

가다.

리액티브 프로그래밍은 처음에는 새로운 패러다임의 이름처럼 들리지만 실제로는 이벤트 기반 접근 방식을 사용하여 비동기 데이터 스트림으로 작업하는 프로그래밍 방법을 나타냅니다. 지속적으로 최신 데이터를 기반으로 반응 시스템은 일련의 이벤트를 실행하여 이에 응답합니다.
리액티브 프로그래밍은 다음과 같이 정의할 수 있는 Observer 디자인 패턴을 따릅니다. 한 개체에서 상태 변경이 발생하면 다른 모든 개체에 그에 따라 알리고 업데이트됩니다. 따라서 변경 사항에 대해 이벤트를 폴링하는 대신 관찰자가 이벤트를 처리할 수 있도록 이벤트가 비동기식으로 푸시됩니다. 이 예제에서 관찰자는 이벤트가 전달될 때 실행되는 함수입니다. 그리고 언급된 데이터 스트림은 실제로 관찰 가능한 것입니다.

거의 모든 언어와 프레임워크는 생태계에서 이 접근 방식을 사용하며 최신 버전의 Java도 예외는 아닙니다. 이 기사에서는 Java EE 8 및 Java 8 기능에서 최신 버전의 JAX-RS를 사용하여 반응형 프로그래밍을 적용하는 방법을 설명합니다.

반응성 선언문

Reactive Manifesto에는 애플리케이션이 더 유연하고, 느슨하게 결합되고, 확장하기 쉬워서 반응성이 있어야 하는 네 가지 기본 측면이 나열되어 있습니다. 이는 애플리케이션이 응답성이 뛰어나고 유연하며(따라서 확장 가능) 복원력이 있고 메시지 중심적이어야 한다고 명시합니다.

기본 목표는 진정한 반응형 애플리케이션입니다. 하나의 큰 스레드가 사용자 요청을 처리하고 작업이 완료되면 해당 스레드가 원래 요청자에게 응답을 다시 보내는 애플리케이션이 있다고 가정해 보겠습니다. 애플리케이션이 처리할 수 있는 것보다 더 많은 요청을 받으면 이 스레드는 병목 현상이 발생하고 애플리케이션은 이전 응답성을 잃습니다. 응답성을 유지하려면 애플리케이션이 확장 가능하고 복원력이 있어야 합니다. 자동 복구 기능이 있는 애플리케이션은 안정적인 것으로 간주될 수 있습니다. 대부분의 개발자 경험에 따르면 메시지 중심 아키텍처만이 애플리케이션의 확장성, 안정성 및 반응성을 가능하게 합니다.

반응형 프로그래밍은 Java 8 및 Java EE 8에서 채택되기 시작했습니다. Java 언어는 CompletionStage 및 CompletableFuture 구현과 같은 개념을 도입했으며 Java는 JAX-RS의 Reactive Client API와 같은 사양에서 이러한 기능을 사용하기 시작했습니다.

JAX-RS 2.1 반응형 클라이언트 API

Java EE 8 애플리케이션에서 반응형 프로그래밍을 어떻게 사용할 수 있는지 살펴보겠습니다. 프로세스를 이해하려면 Java EE API에 대한 기본 지식이 필요합니다.

JAX-RS 2.1에서는 반응형 프로그래밍을 지원하는 REST 클라이언트를 생성하는 새로운 방법을 도입했습니다. JAX-RS에서 제공되는 기본 호출자 구현은 동기식입니다. 즉, 생성 중인 클라이언트가 서버의 끝점에 차단 호출을 보냅니다. 구현 예가 목록 1에 나와 있습니다.

응답 응답 = ClientBuilder.newClient() .target("http://localhost:8080/service-url") .request() .get();
버전 2.0부터 JAX-RS는 목록 2에 표시된 것처럼 async() 메서드에 대한 간단한 호출을 통해 클라이언트 API에서 비동기 호출자를 생성하기 위한 지원을 제공합니다.

미래 response = ClientBuilder.newClient() .target("http://localhost:8080/service-url") .request() .async() .get();
클라이언트에서 비동기 호출자를 사용하면 javax.ws.rs.core.Response 유형의 Future 인스턴스가 반환됩니다. 이로 인해 응답을 폴링하거나 future.get()을 호출하거나 사용 가능한 HTTP 응답이 있을 때 호출될 콜백을 등록할 수 있습니다. 두 구현 모두 비동기 프로그래밍에 적합하지만 콜백을 그룹화하거나 이러한 비동기 실행 최소값에 조건부 사례를 추가하려는 경우 상황이 더 복잡해지는 경향이 있습니다.

JAX-RS 2.1은 클라이언트 어셈블리용 새로운 JAX-RS Reactive Client API를 사용하여 이러한 문제를 극복하는 반응적 방법을 제공합니다. 클라이언트 빌드 중에 rx() 메서드를 호출하는 것만큼 간단합니다. 목록 3에서 rx() 메소드는 클라이언트가 실행되는 동안 존재하는 반응적 호출자를 반환하고 클라이언트는 CompletionStage.rx() 유형의 응답을 반환합니다. 이를 통해 간단한 방법으로 동기 호출자에서 비동기 호출자로 전환할 수 있습니다. 부르다.

완료단계 response = ClientBuilder.newClient() .target("http://localhost:8080/service-url") .request() .rx() .get();
완료단계<Т>Java 8에 도입된 새로운 인터페이스입니다. 이름에서 알 수 있듯이 더 큰 계산 내의 한 단계가 될 수 있는 계산을 나타냅니다. 이는 JAX-RS에 포함된 Java 8 반응성의 유일한 대표입니다.
응답 인스턴스를 받은 후 목록 4에 표시된 것처럼 응답이 사용 가능해지면 비동기적으로 실행될 코드 조각을 제공할 수 있는 AcceptAsync()를 호출할 수 있습니다.

Response.thenAcceptAsync(res -> ( 온도 t = res.readEntity(Temperature.class); //t로 작업 수행 ));
REST 엔드포인트에 반응성 추가

반응적 접근 방식은 JAX-RS의 클라이언트측에만 국한되지 않습니다. 서버 측에서도 사용할 수 있습니다. 예를 들어, 먼저 단일 목적지에 대한 위치 목록을 요청할 수 있는 간단한 스크립트를 작성하겠습니다. 각 위치에 대해 온도 값을 얻기 위해 다른 지점에 대한 위치 데이터를 사용하여 별도의 호출을 수행합니다. 대상 간의 상호 작용은 그림 1과 같습니다.

그림 1. 대상 간 상호작용

먼저 범위 모델을 정의한 다음 각 모델에 대한 서비스를 정의합니다. Listing 5에서는 Location 및 Temp 클래스를 래핑하는 Forecast 클래스를 정의하는 방법을 보여줍니다.

공용 클래스 온도( 개인 이중 온도; 개인 문자열 스케일; // getters & setters ) 공용 클래스 Location( 문자열 이름; public Location() () 공용 Location(문자열 이름) ( this.name = name; ) // getters & setters ) 공개 클래스 Forecast ( 비공개 Location 위치; 비공개 온도 온도; 공개 Forecast(위치 위치) ( this.location = location; ) 공개 Forecast setTemperature(최종 온도 온도) ( this.temp = 온도; return this; ) // getters )
예측 목록을 래핑하기 위해 ServiceResponse 클래스가 목록 6에 구현되었습니다.

공용 클래스 ServiceResponse( 개인 긴 처리 시간; 개인 목록 예측 = 새로운 ArrayList<>(); 공개 무효 setProcessingTime(긴 처리 시간) ( this.processingTime = 처리 시간; ) 공개 ServiceResponse 예측(목록 예측) ( this.forecasts = 예측; return this; ) // getters )
목록 7에 표시된 LocationResource는 /location 경로와 함께 반환된 세 가지 샘플 위치를 정의합니다.

@Path("/location") 공용 클래스 LocationResource( @GET @Produces(MediaType.APPLICATION_JSON) 공용 응답 getLocations()( 목록 위치 = 새 ArrayList<>(); 위치.추가(새 위치("런던")); 위치.추가(새 위치("이스탄불")); 위치.add(새 위치("프라하")); Response.ok를 반환합니다(새 GenericEntity >(위치)()).build(); ) )
Listing 8에 표시된 ThermalResource는 지정된 위치에 대해 30~50 사이에서 무작위로 생성된 온도 값을 반환합니다. 센서 판독값을 시뮬레이션하기 위해 구현에 500ms의 지연이 추가되었습니다.

@Path("/온도") 공개 클래스 온도 리소스( @GET @Path("/(city)") @Produces(MediaType.APPLICATION_JSON) 공개 응답 getAverageTemperature(@PathParam("city") 문자열 cityName) ( 온도 온도 = 신규 온도(); 온도.setTemperature((double) (new Random().nextInt(20) + 30)); 온도.setScale("Celsius"); try ( Thread.sleep(500); ) catch (InterruptedException 무시) ( 무시됨.printStackTrace(); ) Response.ok(온도).build() 반환 ) )
먼저 모든 위치를 반환하는 동기 ForecastResource(목록 9 참조)의 구현을 보여드리겠습니다. 그런 다음 각 위치에 대해 온도 서비스를 호출하여 섭씨 온도 값을 가져옵니다.

@Path("/forecast") 공용 클래스 ForecastResource ( @Uri("location") 개인 WebTarget locationTarget; @Uri("온도/(도시)") 개인 WebTarget 온도Target; @GET @Produces(MediaType.APPLICATION_JSON) 공용 응답 getLocationsWithTemperature () ( 긴 startTime = System.currentTimeMillis(); ServiceResponse 응답 = 새로운 ServiceResponse(); 목록 위치 = locationTarget .request() .get(new GenericType >()()); 위치.forEach(위치 -> ( 온도 온도 = 온도 목표 .resolveTemplate("city", location.getName()) .request() .get(Temperature.class); response.getForecasts().add(새 예측(위치) .setTemperature(온도)); 긴 endTime = System.currentTimeMillis(); response.setProcessingTime(endTime - startTime); return Response.ok(응답).build(); ) )
예측 목적지를 /forecast 로 쿼리하면 Listing 10과 비슷한 출력을 얻게 됩니다. 쿼리 처리 시간은 1.533ms가 걸렸습니다. 이는 서로 다른 세 위치에서 동시에 온도 값을 쿼리하면 총 1.5ms가 되므로 의미가 있습니다. ms.

( "예보": [ ( "위치": ( "이름": "런던"), "온도": ( "규모": "섭씨", "온도": 33 ) ), ( "위치": ( "이름 ": "이스탄불" ), "온도": ( "규모": "섭씨", "온도": 38 ) ), ( "위치": ( "이름": "프라하" ), "온도": ( "규모 ": "섭씨", "온도": 46 ) ) ], "processingTime": 1533 )
지금까지는 모든 것이 계획대로 진행되고 있습니다. 이제 모든 위치를 검색한 후 각 위치에 대한 호출이 병렬로 이루어질 수 있는 서버측에 반응형 프로그래밍을 도입할 시간입니다. 이는 앞서 설명한 동기 흐름을 확실히 향상시킬 수 있습니다. 이는 예측 서비스의 반응적 버전 정의를 보여주는 목록 11에서 수행됩니다.

@Path("/reactiveForecast") 공용 클래스 ForecastReactiveResource( @Uri("location") 개인 WebTarget locationTarget; @Uri("온도/(도시)") 개인 WebTarget 온도Target; @GET @Produces(MediaType.APPLICATION_JSON) 공용 void getLocationsWithTemperature (@Suspended final AsyncResponse async) ( long startTime = System.currentTimeMillis(); // 위치를 검색하는 단계 생성 CompletionStage > locationCS = locationTarget.request() .rx() .get(new GenericType >() ()); // 위에서 설명한 위치 단계에서 별도의 단계를 생성하여 // 예측 목록을 수집합니다. // 하나의 큰 CompletionStage final CompletionStage > ForecastCS = locationCS.thenCompose(locations -> ( // 예측을 수신할 단계를 // CompletionStage 목록으로 생성합니다. > ForecastList = // 위치를 스트리밍하고 // 각각을 개별적으로 처리합니다. location.stream().map(location -> ( // // 한 도시의 온도 값만 // 이름으로 얻기 위한 단계를 만듭니다. final 완료단계 tempCS = 온도 목표 .resolveTemplate("city", location.getName()) .request() .rx() .get(Temperature.class); // 그런 다음 위치 및 온도 값이 포함된 // 예측 인스턴스를 포함하는 // CompletableFuture를 만듭니다. return CompletableFuture.completedFuture(new Forecast(location)) .thenCombine(tempCS, Forecast::setTemperature); )).collect(Collectors.toList()); // 최종 CompletableFuture 인스턴스를 반환합니다. // 제시된 모든 완료 가능 미래 객체가 // 완료됩니다. return CompletableFuture.allOf(forecastList.toArray(new CompletableFuture)) .thenApply(v -> ForecastList.stream() .map(CompletionStage:: toCompletableFuture) .map(CompletableFuture::join) .collect(Collectors.toList())); ))); // 처리 시간과 함께 // 전체 예측 목록을 포함하는 // ServiceResponse 인스턴스를 생성합니다. // future를 생성하고 // ForecastCS와 결합하여 예측값을 얻음 // 서비스 응답에 삽입 CompletableFuture.completedFuture(new ServiceResponse()) .thenCombine(forecastCS, ServiceResponse::forecasts) .whenCompleteAsync((response, throwable ) - > ( response.setProcessingTime(System.currentTimeMillis() - startTime); async.resume(response); )); ) )
리액티브 구현은 언뜻 보면 복잡해 보일 수 있지만 자세히 살펴보면 매우 간단하다는 것을 알 수 있습니다. ForecastReactiveResource 구현에서는 먼저 JAX-RS Reactive Client API를 사용하여 위치 서비스에 대한 클라이언트 호출을 생성합니다. 위에서 언급했듯이 이는 Java EE 8용 추가 기능이며 rx() 메서드를 사용하여 간단히 반응 호출을 생성하는 데 도움이 됩니다.

이제 예측 목록을 수집하기 위해 위치를 기반으로 새 단계를 만듭니다. 이는 ForecastCS라는 하나의 대규모 완료 단계에 예측 목록으로 저장됩니다. 최종적으로는 ForecastCS만을 사용하여 서비스 호출 응답을 생성하겠습니다.

이제 ForecastList 변수에 정의된 완료 단계 목록 형태로 예측을 수집해 보겠습니다. 각 예측에 대한 완료 단계를 생성하기 위해 위치 데이터를 전달한 다음 다시 도시 이름으로 온도 서비스를 호출하는 JAX-RS Reactive Client API를 사용하여 tempCS 변수를 생성합니다. 여기서는 클라이언트를 빌드하기 위해 해결Template() 메소드를 사용하고 이를 통해 도시 이름을 빌더에 매개변수로 전달할 수 있습니다.

마지막 스트리밍 단계로 CompletableFuture.completedFuture() 를 호출하여 새 Forecast 인스턴스를 매개변수로 전달합니다. 이 미래를 tempCS 단계와 결합하여 반복되는 위치에 대한 온도 값을 얻습니다.

목록 11의 CompletableFuture.allOf() 메소드는 완료 단계 목록을 ForecastCS 로 변환합니다. 이 단계를 실행하면 제공된 모든 완료 가능한 미래 객체가 완료될 때 완료 가능한 큰 미래 인스턴스가 반환됩니다.

서비스 응답은 ServiceResponse 클래스의 인스턴스이므로 완료된 미래를 생성한 다음 ForecastCS 완료 단계를 예측 목록과 결합하고 서비스 응답 시간을 계산합니다.

물론 리액티브 프로그래밍은 서버측이 비동기적으로 실행되도록 강제합니다. 서버가 요청자에게 응답을 다시 보낼 때까지 클라이언트 측은 차단됩니다. 이 문제를 극복하기 위해 SSE(Server Sent Events)를 사용하여 부분 응답이 가능한 즉시 보내도록 하여 각 위치의 온도 값을 하나씩 클라이언트에 보낼 수 있습니다. ForecastReactiveResource의 출력은 목록 12에 표시된 것과 유사합니다. 출력에 표시된 것처럼 처리 시간은 515ms입니다. 이는 단일 위치에서 온도 값을 검색하는 데 이상적인 실행 시간입니다.

( "예보": [ ( "위치": ( "이름": "런던"), "온도": ( "규모": "섭씨", "온도": 49 ) ), ( "위치": ( "이름 ": "이스탄불" ), "온도": ( "규모": "섭씨", "온도": 32 ) ), ( "위치": ( "이름": "프라하" ), "온도": ( "규모 ": "섭씨", "온도": 45 ) ) ], "processingTime": 515 )
결론

이 기사의 예에서는 위치 및 온도 서비스를 사용하여 예측을 얻는 동기식 방법을 먼저 보여주었습니다. 그런 다음 서비스 호출 간에 비동기 처리가 발생하도록 허용하는 반응형 접근 방식으로 전환했습니다. Java 8에서 사용할 수 있는 CompletionStage 및 CompletableFuture 클래스와 함께 Java EE 8에서 JAX-RS Reactive Client API를 사용하면 반응형 프로그래밍을 통해 비동기 처리의 힘이 발휘됩니다.

리액티브 프로그래밍은 단순히 동기 모델에서 비동기 모델을 구현하는 것 이상입니다. 또한 중첩 단계와 같은 개념으로 작업하기가 더 쉬워집니다. 더 많이 사용할수록 병렬 프로그래밍에서 복잡한 시나리오를 관리하는 것이 더 쉬워집니다.

관심을 가져주셔서 감사합니다. 언제나처럼 여러분의 의견과 질문을 환영합니다.

사이트 개발을 위해 일부 자금을 돕고 이체할 수 있습니다.

확장성, 내결함성 및 응답성에 대한 증가하는 요구를 충족하고 멀티 코어 환경과 클라우드 컴퓨팅 모두에 없어서는 안 될 현대 프로그래밍 분야에 대해 이야기하고 이에 대한 공개 온라인 과정을 소개하고 싶습니다. 단지 며칠.

반응형 프로그래밍에 대해 들어본 적이 없더라도 괜찮습니다. 이는 동시성과 이벤트 중심성 및 비동기성을 결합하여 빠르게 발전하는 분야입니다. 반응성은 모든 웹 서비스 및 분산 시스템에 내재되어 있으며 많은 고성능, 고도의 병렬 시스템의 핵심 역할을 합니다. 간단히 말해서, 과정 작성자는 활성 주제 간에 교환되는 비동기 데이터 스트림에 의해 조정 및 조정되고 분산 상태를 갖는 병렬 시스템에 대한 기능적 프로그래밍(고차 기능 포함)의 자연스러운 확장으로 반응형 프로그래밍을 고려할 것을 제안합니다. 배우.

이는 Reactive Manifesto에 더 이해하기 쉬운 용어로 설명되어 있습니다. 아래에서 주요 조항을 다시 설명하고 전체 번역은 Habré에 게시됩니다. Wikipedia에 따르면 용어는 반응형 프로그래밍꽤 오랫동안 존재해 왔으며 다양한 정도의 이국성을 실제로 적용했지만 Typesafe Inc.의 이니셔티브 그룹인 Reactive Manifesto 작성자의 노력 덕분에 아주 최근에 개발 및 배포에 대한 새로운 자극을 받았습니다. Typesafe는 함수형 프로그래밍 커뮤니티에서 아름다운 Scala 언어와 혁신적인 Akka 병렬 플랫폼의 저자가 설립한 회사로 알려져 있습니다. 그들은 이제 자신의 회사를 세계 최초의 차세대 제트 플랫폼 창시자로 자리매김하고 있습니다. 해당 플랫폼을 사용하면 복잡한 사용자 인터페이스를 신속하게 개발할 수 있으며 병렬 컴퓨팅 및 멀티스레딩에 대한 새로운 수준의 추상화를 제공하여 예측 가능한 확장이 보장되어 고유한 위험을 줄일 수 있습니다. Reactive Manifesto의 아이디어를 실제로 적용하고 개발자가 현대적인 요구 사항을 충족하는 애플리케이션을 개념화하고 만들 수 있도록 합니다.

리액티브 프로그래밍의 원리 대규모 공개 온라인 강좌를 수강하면 프레임워크와 리액티브 프로그래밍에 익숙해질 수 있습니다. 이 과정은 Martin Odersky의 Scala에 대한 함수형 프로그래밍 원리의 연속입니다. 이 과정에는 100,000명이 넘는 참가자가 있고 참가자의 대규모 공개 온라인 과정에 대해 세계에서 가장 높은 성공률 중 하나입니다. Scala 언어의 창시자와 함께 .NET에서 반응형 프로그래밍을 위한 Rx 환경을 개발한 Eric Meyer와 현재 Typesafe에서 Akka 개발 팀을 이끌고 있는 Roland Kuhn이 새로운 과정을 진행합니다. 이 과정에서는 반응형 프로그래밍의 핵심 요소를 다루고, 확장 가능하고 내결함성이 있는 이벤트 중심 시스템을 설계하는 데 이러한 요소가 어떻게 사용되는지 보여줍니다. 교육 자료는 짧은 프로그램으로 설명되어 있으며 각 작업은 소프트웨어 프로젝트입니다. 모든 작업이 성공적으로 완료되면 참가자는 인증서를 받습니다. (물론 참가와 인증서 모두 무료입니다.) 이 과정은 7주 동안 진행되며 11월 4일 월요일에 시작됩니다. 자세한 개요와 소개 동영상은 코스 페이지(https://www.coursera.org/course/reactive)에서 확인하실 수 있습니다.

관심이 있거나 의심스러운 분들을 위해 Reactive Manifesto의 기본 개념에 대한 요약 요약을 제공합니다. 저자는 최근 몇 년간 신청 요구 사항이 크게 변경되었음을 언급했습니다. 오늘날 애플리케이션은 모바일 장치부터 수천 개의 멀티 코어 프로세서를 갖춘 클라우드 클러스터까지 모든 환경에 배포됩니다. 이러한 환경은 소프트웨어와 기술에 대한 새로운 요구를 제기합니다. 이전 세대 아키텍처에서는 관리형 서버와 컨테이너에 중점을 두었고, 고가의 추가 하드웨어, 독점 솔루션, 멀티스레딩을 통한 병렬 컴퓨팅을 통해 확장성을 달성했습니다. 소비자 및 기업 산업 환경 모두에서 점점 더 널리 퍼지고 있는 네 가지 중요한 기능을 식별할 수 있는 새로운 아키텍처가 이제 진화하고 있습니다. 이러한 아키텍처를 갖춘 시스템은 이벤트 기반, 확장 가능, 내결함성 및 빠른 응답을 제공합니다. 반응이 좋습니다. 이는 멀티 코어 및 클라우드 환경에 배포할 준비가 된 자가 복구, 확장 가능한 애플리케이션 스택을 통해 지원되는 실시간 느낌의 원활한 사용자 경험을 제공합니다. 리액티브 아키텍처의 네 가지 특성은 각각 전체 기술 스택에 적용되며, 이는 계층화된 아키텍처의 링크와 구별됩니다. 좀 더 자세히 살펴보겠습니다.


이벤트 중심애플리케이션은 비동기 통신 구성 요소를 가정하고 느슨하게 결합된 설계를 구현합니다. 즉, 메시지를 보내는 사람과 받는 사람은 서로에 대한 정보나 메시지 전송 방법에 대한 정보가 필요하지 않으므로 통신 내용에 집중할 수 있습니다. 느슨하게 결합된 구성 요소는 시스템의 유지 관리성, 확장성 및 발전을 크게 향상시킬 뿐만 아니라 상호 작용의 비동기성 및 비차단 특성을 통해 리소스의 상당 부분을 확보하고 호출 시간을 단축하며 영형기존 애플리케이션에 비해 처리량이 더 높습니다. 반응형 아키텍처의 나머지 기능을 가능하게 만드는 것은 이벤트 중심 특성입니다.

확장성반응형 프로그래밍의 맥락에서 이는 부하 변경에 대한 시스템의 응답입니다. 필요에 따라 컴퓨팅 노드를 추가하거나 해제하는 기능을 통해 달성되는 탄력성입니다. 낮은 결합, 비동기 메시징 및 위치 투명성을 통해 애플리케이션의 배포 방법과 토폴로지는 배포 시간 결정과 구성 및 로드 응답 알고리즘의 문제가 됩니다. 따라서 컴퓨터 네트워크는 처음에는 명시적인 분산 특성을 지닌 응용 프로그램의 일부가 됩니다.

결함 허용반응형 아키텍처도 설계의 일부가 되므로 중복 서버를 통해 지속적인 시스템 가용성을 보장하고 장애 발생 시 제어권을 넘겨받는 기존 접근 방식과 크게 다릅니다. 이러한 시스템의 복원력은 개별 구성 요소의 오류에 올바르게 응답하고, 해당 오류를 발생시킨 메시지 형식으로 해당 컨텍스트를 저장하여 이러한 오류를 격리하고, 이러한 메시지를 다른 구성 요소에 전달하여 오류를 해결하는 방법을 결정할 수 있는 능력을 통해 달성됩니다. 오류를 처리하세요. 이 접근 방식을 사용하면 시스템 자체를 사용하여 오류를 등록, 격리 및 처리하기 위해 명시적 선언 형식으로 공식화되는 오류 처리 논리를 분리하여 애플리케이션의 비즈니스 논리를 순수하게 유지할 수 있습니다. 이러한 자가 치유 시스템을 구축하기 위해 구성 요소는 계층적으로 정렬되고 문제는 문제를 해결할 수 있는 수준으로 확대됩니다.

그리고 마지막으로 민감도- 이는 부하 및 오류에 관계없이 사용자 입력에 응답하는 시스템의 능력입니다. 이러한 응용 프로그램은 사용자를 상호 작용에 참여시키고 시스템과의 긴밀한 연결 느낌을 생성하며 현재 작업을 수행하기에 충분한 장비입니다. 응답성은 실시간 시스템과 관련이 있을 뿐만 아니라 광범위한 애플리케이션에도 필요합니다. 더욱이, 장애가 발생한 순간에도 신속하게 대응할 수 없는 시스템은 내결함성이 있다고 간주할 수 없습니다. 응답성은 관찰 가능한 모델, 이벤트 스트림 및 상태 저장 클라이언트를 사용하여 달성됩니다. 관찰 가능한 모델은 상태가 변경될 때 이벤트를 생성하고 사용자와 시스템 간의 실시간 상호 작용을 활성화하며, 이벤트 스트림은 비차단 비동기 변환 및 통신을 통해 이 상호 작용이 구축되는 추상화를 제공합니다.

따라서 반응형 애플리케이션은 현대 소프트웨어 개발의 광범위한 문제를 해결하기 위한 균형 잡힌 접근 방식을 나타냅니다. 이벤트 중심 기반을 기반으로 구축되어 확장성과 내결함성을 보장하고 풍부하고 응답성이 뛰어난 사용자 경험을 지원하는 데 필요한 도구를 제공합니다. 저자는 점점 더 많은 시스템이 반응형 선언문의 원칙을 준수할 것으로 예상합니다.

또한, 번역 없이 강의 계획서를 제공합니다. 여기까지 읽으셨고 여전히 관심이 있으신 경우를 대비해,

1주차: 함수형 프로그래밍의 원리 검토: 대체 모델, for-표현 및 모나드와의 관계. for-expression의 새로운 구현인 무작위 값 생성기를 도입합니다. 무작위 테스트에서 이것이 어떻게 사용될 수 있는지 보여주고 이 아이디어를 구현하는 도구인 ScalaCheck에 대한 개요를 제공합니다.

2주차: 함수형 프로그래밍 및 변경 가능한 상태. 객체를 변경 가능하게 만드는 것은 무엇입니까? 이것이 대체 모델에 어떤 영향을 미치는지. 확장된 예: 디지털 회로 시뮬레이션

3주차: 선물. for-expression을 구체적인 구문으로 사용하여 future를 또 다른 모나드로 도입합니다. 스레드 차단을 방지하기 위해 future를 구성하는 방법을 보여줍니다. 크로스 스레드 오류 처리에 대해 설명합니다.

4주차: 반응형 스트림 처리. 스트림에 대한 반응형 계산으로 미래를 일반화합니다. 스트림 운영자.

5주차: 배우들. 행위자 모델, 일관성의 캡슐화된 단위인 행위자, 비동기식 메시지 전달을 소개하고 다양한 메시지 전달 의미(최대 한 번, 최소 한 번, 정확히 한 번) 및 최종 일관성에 대해 논의합니다.

6주차: 감독. 오류 구체화, 계층적 오류 처리, 오류 커널 패턴, 수명 주기 모니터링을 소개하고 일시적 및 지속적 상태에 대해 논의합니다.

7주차: 대화 패턴. 흐름 제어를 위한 행위자 및 패턴 간의 대화 상태 관리, 탄력성 또는 로드 밸런싱을 위해 행위자 풀로 메시지 라우팅, 안정적인 전달을 달성하기 위한 수신 확인에 대해 논의합니다.