ReactiveCocoa vs RxSwift - ưu và nhược điểm?


256

Vì vậy, bây giờ với swift, người ReactiveCocoa đã viết lại nó trong phiên bản 3.0 cho swift

Ngoài ra, có một dự án khác được gọi là RxSwift .

Tôi tự hỏi liệu mọi người có thể thêm thông tin về sự khác biệt trong thiết kế / api / triết lý của hai khung là gì không (làm ơn, theo tinh thần của SO, hãy bám vào những điều đúng, thay vì ý kiến ​​về cái nào là "tốt nhất")

[Lưu ý cho các mod StackOverflow: Câu hỏi này KHÔNG có câu trả lời dứt khoát, câu trả lời là sự khác biệt giữa hai khung. Tôi nghĩ nó cũng rất có chủ đề cho SO]

Để bắt đầu, ấn tượng ban đầu của tôi khi đọc ReadMe của họ là:

  • Là một người quen thuộc với C # Rx "thực" từ microsoft, RxSwift trông dễ nhận biết hơn rất nhiều.
  • ReactiveCococa dường như đã đi vào không gian riêng của nó bây giờ, giới thiệu các khái niệm trừu tượng mới như Tín hiệu so với Tín hiệu và Nâng hàng. Một mặt điều này dường như làm rõ một số tình huống (tín hiệu nóng so với lạnh) nhưng mặt khác điều này dường như làm tăng sự phức tạp của khung rất nhiều

Câu hỏi của bạn đặc biệt yêu cầu "ý kiến". Bạn có thể vui lòng tua lại? Tôi sẽ sẵn sàng rút lại phiếu bầu gần của mình sau đó.
Sulthan

2
Bạn có thể thoát khỏi "thêm ý kiến ​​của họ", bởi vì sự khác biệt là sự thật, không phải ý kiến. Sau đó, bạn có thể thích hoặc không thích một số tính năng của RAC / RxSwift, nhưng sự khác biệt là rõ ràng.
bontoJR

1
hahaha, di chuyển tốt về "ghi chú cho mod"!
ming yeow

1
Đổi tên câu hỏi: Sự khác biệt giữa ReactiveCocoa và RxSwift. Tôi nghĩ mọi thứ sẽ trở thành "sự thật", và câu hỏi này là di sản.
hqt

1
Ngay cả giải pháp cũng bắt đầu bằng "Đây là một câu hỏi rất hay." : |
Iulian Onofrei

Câu trả lời:


419

Đây là một câu hỏi rất hay. So sánh hai thế giới là rất khó. Rx là một cổng của phần mở rộng Reactive trong các ngôn ngữ khác như C #, Java hoặc JS.

Reactive Ca cao được lấy cảm hứng từ Lập trình Phản ứng Chức năng , nhưng trong những tháng trước, cũng đã được chỉ ra là lấy cảm hứng từ Phần mở rộng Phản ứng . Kết quả là một khung chia sẻ một số thứ với Rx, nhưng có tên với nguồn gốc trong FRP.

Điều đầu tiên phải nói là cả RAC và RxSwift đều không phải là các triển khai lập trình phản ứng chức năng , theo định nghĩa của Conal về khái niệm này. Từ thời điểm này, mọi thứ có thể được giảm xuống thành cách mỗi khung xử lý các tác dụng phụ và một vài thành phần khác.

Hãy nói về cộng đồng và công cụ siêu công nghệ :

  • RAC là một dự án 3 năm tuổi, được sinh ra ở Objective-C sau đó được chuyển sang Swift (có cầu nối) cho phiên bản 3.0, sau khi hoàn toàn bỏ công việc đang diễn ra trên Objective-C.
  • RxSwift là một dự án vài tháng tuổi và dường như có một động lực trong cộng đồng ngay bây giờ. Một điều quan trọng đối với RxSwift là thuộc tổ chức ReactiveX và tất cả các triển khai khác đều hoạt động theo cùng một cách, học cách đối phó với RxSwift sẽ khiến việc làm việc với Rx.Net, RxJava hoặc RxJS trở thành một nhiệm vụ đơn giản và chỉ là vấn đề cú pháp ngôn ngữ. Tôi có thể nói rằng dựa trên triết lý học một lần, áp dụng ở mọi nơi .

Bây giờ là thời gian cho các công nghệ.

Thực thể sản xuất / quan sát

RAC 3.0 có 2 thực thể chính Signalvà , thực thể SignalProducerđầu tiên xuất bản các sự kiện bất kể thuê bao có được đính kèm hay không, thực thể thứ hai yêu cầu startphải thực sự có tín hiệu / sự kiện được tạo ra. Thiết kế này đã được tạo ra để phân tách khái niệm tẻ nhạt của các vật quan sát nóng và lạnh, đó là nguồn gây nhầm lẫn cho rất nhiều nhà phát triển. Đây là lý do tại sao sự khác biệt có thể được giảm xuống bằng cách họ quản lý các tác dụng phụ .

Trong RxSwift, SignalSignalProducerdịch sang Observable, nghe có vẻ khó hiểu, nhưng 2 thực thể này thực sự giống nhau trong thế giới Rx. Một thiết kế với Observables trong RxSwift phải được tạo ra xem xét nếu chúng nóng hay lạnh, nó có thể nghe có vẻ phức tạp không cần thiết, nhưng một khi bạn hiểu cách chúng hoạt động (và một lần nữa nóng / lạnh / ấm chỉ là về các tác dụng phụ trong khi đăng ký / quan sát ) họ có thể được thuần hóa.

Ở cả hai thế giới, khái niệm đăng ký về cơ bản là giống nhau, có một chút khác biệt mà RAC đã giới thiệu và là interruptionsự kiện khi một sự kiện Signalđược xử lý trước khi sự kiện hoàn thành được gửi đi. Để tóm tắt cả hai có các loại sự kiện sau đây:

  • Next, để tính giá trị nhận mới
  • Error, để tính toán một lỗi và hoàn thành luồng, hủy đăng ký tất cả các nhà quan sát
  • Complete, để đánh dấu luồng là đã hoàn thành hủy đăng ký tất cả các nhà quan sát

Ngoài ra, RAC interruptedđược gửi khi a Signalđược xử lý trước khi hoàn thành chính xác hoặc có lỗi.

Viết thủ công

Trong RAC, Signal/ SignalProducerlà các thực thể chỉ đọc, chúng không thể được quản lý từ bên ngoài, điều tương tự là Observabletrong RxSwift. Để biến a Signal/ SignalProducerthành một thực thể có thể ghi, bạn phải sử dụng pipe()hàm để trả về một mục được điều khiển thủ công. Trên không gian Rx, đây là một loại khác được gọi là Subject.

Nếu khái niệm đọc / ghi nghe có vẻ lạ lẫm, một sự tương tự tốt đẹp với Future/ Promisecó thể được thực hiện. A Futurelà một trình giữ chỗ chỉ đọc, như Signal/ SignalProducerObservable, mặt khác, một Promisecó thể được thực hiện thủ công, như cho pipe()Subject.

Lập lịch

Thực thể này khá giống nhau ở cả hai thế giới, cùng một khái niệm, nhưng RAC chỉ là nối tiếp, thay vào đó, các tính năng của RxSwift cũng đồng thời lên lịch.

Thành phần

Thành phần là tính năng chính của Lập trình Phản ứng. Soạn luồng là bản chất của cả hai khung, trong RxSwift chúng cũng được gọi là chuỗi .

Tất cả các thực thể có thể quan sát được trong RxSwift đều thuộc loại ObservableType, vì vậy chúng tôi soạn các trường hợp của SubjectObservablevới cùng các toán tử, mà không cần quan tâm thêm.

Trên không gian RAC, SignalSignalProducerlà 2 thực thể khác nhau và chúng ta phải liftvề SignalProducerđể có thể soạn những gì được sản xuất với các trường hợp Signal. Hai thực thể có toán tử riêng, vì vậy khi bạn cần trộn mọi thứ, bạn phải đảm bảo có một toán tử nào đó, mặt khác bạn quên đi các vật quan sát nóng / lạnh.

Về phần này, Colin Eberhardt đã tóm tắt nó một cách độc đáo:

Nhìn vào API hiện tại, các hoạt động tín hiệu chủ yếu tập trung vào sự kiện 'tiếp theo', cho phép bạn chuyển đổi các giá trị, bỏ qua, trì hoãn, kết hợp và quan sát trên các luồng khác nhau. Trong khi đó, API của nhà sản xuất tín hiệu chủ yếu liên quan đến các sự kiện vòng đời tín hiệu (đã hoàn thành, lỗi), với các hoạt động bao gồm sau đó, FlatMap, TakeUntil và bắt.

Thêm

RAC cũng có khái niệm ActionProperty, trước đây là một loại để tính toán các tác dụng phụ, chủ yếu liên quan đến tương tác của người dùng, sau này rất thú vị khi quan sát một giá trị để thực hiện một nhiệm vụ khi giá trị đã thay đổi. Trong RxSwift, Actiondịch lại một lần nữa Observable, điều này được thể hiện độc đáo trong RxCocoa, một sự tích hợp các nguyên thủy Rx cho cả iOS và Mac. Các RAC Propertycó thể được dịch thành Variable(hoặc BehaviourSubject) trong RxSwift.

Điều quan trọng là phải hiểu rằng Property/ Variablelà cách chúng ta phải kết nối thế giới bắt buộc với bản chất khai báo của Lập trình phản ứng, vì vậy đôi khi là thành phần cơ bản khi xử lý các thư viện bên thứ ba hoặc các chức năng cốt lõi của không gian iOS / Mac.

Phần kết luận

RAC và RxSwift là 2 quái thú hoàn toàn khác nhau, trước đây có lịch sử lâu đời trong không gian Ca cao và rất nhiều người đóng góp, sau này còn khá trẻ, nhưng dựa vào các khái niệm đã được chứng minh là có hiệu quả trong các ngôn ngữ khác như Java, JS hoặc .MẠNG LƯỚI. Quyết định nào tốt hơn là ưu tiên. RAC tuyên bố rằng việc phân tách nóng / lạnh có thể quan sát được là cần thiết và đó là tính năng cốt lõi của khung, RxSwift nói rằng sự thống nhất giữa chúng là tốt hơn so với phân tách, một lần nữa chỉ là về cách quản lý / thực hiện các tác dụng phụ.

RAC 3.0 dường như đã đưa ra một số phức tạp bất ngờ trên mục tiêu chính là tách các vật quan sát nóng / lạnh, như khái niệm gián đoạn, tách các toán tử giữa 2 thực thể và đưa ra một số hành vi bắt buộc như startbắt đầu tạo tín hiệu. Đối với một số người, những thứ này có thể là một thứ tốt đẹp để có hoặc thậm chí là một tính năng giết người, đối với một số người khác, chúng có thể chỉ là không cần thiết hoặc thậm chí nguy hiểm. Một điều cần nhớ là RAC đang cố gắng theo kịp các quy ước về Cacao nhiều nhất có thể, vì vậy nếu bạn là một người có kinh nghiệm về ca cao, bạn nên cảm thấy thoải mái hơn khi làm việc với nó thay vì RxSwift.

Mặt khác, RxSwift sống với tất cả các nhược điểm như quan sát nóng / lạnh, nhưng cũng là những điều tốt, của Phần mở rộng phản ứng. Chuyển từ RxJS, RxJava hoặc Rx.Net sang RxSwift là một điều đơn giản, tất cả các khái niệm đều giống nhau, vì vậy điều này làm cho việc tìm tài liệu khá thú vị, có thể là vấn đề tương tự mà bạn đang gặp phải, đã được giải quyết bởi ai đó trong RxJava và giải pháp có thể được áp dụng khi xem xét nền tảng.

Cái nào phải được chọn chắc chắn là vấn đề ưu tiên, từ góc độ khách quan là không thể biết cái nào tốt hơn. Cách duy nhất là kích hoạt Xcode và thử cả hai và chọn một cái mà cảm thấy thoải mái hơn khi làm việc. Chúng là 2 triển khai các khái niệm tương tự nhau, cố gắng đạt được cùng một mục tiêu: đơn giản hóa việc phát triển phần mềm.


24
Đây là một lời giải thích tuyệt vời, @ junior-b! Tuy nhiên, điều đáng nói là RAC mã hóa thông tin loại (bao gồm thiếu lỗi nhờ NoError) trong chính các loại luồng: Signal<T, E: ErrorType>so với Observable<T>. Điều này, cũng như sự phân tách nóng / lạnh, cung cấp lượng thông tin tăng lên vào thời gian biên dịch mà bạn không có RxSwift.
NachoSoto

3
Xin chào @nachosoto, cảm ơn vì những lời tốt đẹp. Tôi nghĩ rằng sự bổ sung được đề xuất sẽ không phù hợp lắm khi so sánh về Lập trình Phản ứng. Đây chắc chắn là một bổ sung tuyệt vời về phía RAC, nhưng đối với tôi, RP là về việc đơn giản hóa lập trình luồng dữ liệu và các yếu tố quan trọng là: xử lý lỗi, tính toán không đồng bộ, quản lý và thành phần tác dụng phụ. Từ góc độ nhà phát triển có vẻ là một tính năng hay, đây là để làm rõ loại lỗi trên mã, nó không thực sự cải thiện khía cạnh xử lý lỗi của khung, tất nhiên đây là ý kiến ​​khiêm tốn của tôi.
bontoJR

3
Điều đáng nói là cho đến nay vẫn còn thiếu các hướng dẫn tốt về RAC, tuy nhiên có một số dự án mẫu tuyệt vời cho RxSwift có ý nghĩa quyết định đối với tôi.
Vadim Bulavin

1
ReactiveCocoa là tốt, cho đến khi họ giới thiệu các chức năng miễn phí, Tín hiệu sản xuất, chung chung với Lỗi. Tôi học RxSwift và tôi có được trải nghiệm tương tự khi làm việc với RxKotlin, RxJS
onmyway133
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.