RxJava sınıfı Flowable'ın yasal olarak 460 yöntemi olabilir mi?


14

Ben sadece RxJava , Java'nın ReactiveX ( Rx ve Reaktif Uzantıları olarak da bilinir) uygulaması ile başlıyorum . Gerçekten bana vurdu o şey kitlesel büyüklüğündeydi RxJava en Akışkan sınıfta : o 460 yöntemleri vardır!

Adil olmak:

  • Aşırı yüklenmiş, toplam yöntem sayısını önemli ölçüde çarptıran birçok yöntem vardır.

  • Belki de bu sınıf parçalanmalıdır, ancak RxJava hakkındaki bilgim ve anlayışım çok sınırlıdır. RxJava yarattı millet mutlaka çok akıllı ve bunlar oluşturmak için seçtiğiniz için geçerli argümanlar muhtemelen sunabilir akabilir kadar çok yöntemlerle.

Diğer yandan:

  • RxJava Java uygulamasıdır Microsoft'un Reaktif Uzantıları ve bu hatta bir yok Akışkan bu körlemesine varolan sınıf taşıma ve Java gibi uygulanmasının bir durum değildir bu yüzden, sınıf.

  • [ Güncelleme: Microsoft: italik olarak önceki bir noktaya dayanarak yanlış olduğu gözlemlenebilir 400 yöntemleri vardır sınıfı, RxJava en için temel olarak kullanılmıştır Gözlemlenebilir sınıf ve Akışkan benzer gözlemlenebilir , ancak kolları verilerin büyük miktarlar için geri-basınç. RxJava ekibi Yani edildi varolan sınıf taşıma. Bu mesaj özgün tasarımını zorlu olmalıydı gözlemlenebilir Microsoft ziyade RxJava en sınıfa Akışkan sınıfa.]

  • RxJava sadece 3 yaşın biraz üzerindedir, bu nedenle iyi ( SOLID ) sınıfı tasarım ilkeleri (Java'nın erken sürümlerinde olduğu gibi) hakkında bilgi eksikliği nedeniyle yanlış tasarlanmış bir kod örneği değildir .

Flowable kadar büyük bir sınıf için tasarımı doğal olarak yanlış görünüyor, ama belki de değil; Bu SE sorusuna bir cevap Bir sınıf yöntemi sayısının sınırı nedir? cevabının " İhtiyacınız olduğu kadar çok yönteme sahip olduğunu" önerdi .

Açıkça, dilden bağımsız olarak onları desteklemek için yasal olarak çok sayıda yönteme ihtiyaç duyan bazı sınıflar vardır, çünkü daha küçük bir şeye kolayca ayrılmazlar ve adil sayıda özellik ve öznitelikleri vardır. Örneğin: dizeler, renkler, elektronik tablo hücreleri, veritabanı sonuç kümeleri ve HTTP istekleri. Sınıfların bu şeyleri temsil etmesi için belki de birkaç düzine yöntemi olması mantıksız görünmüyor.

Ancak Flowable'ın gerçekten 460 yönteme ihtiyacı var mı yoksa zorunlu olarak kötü sınıf tasarımına bir örnek olacak kadar büyük mü?

[Açık olmak gerekirse: Bu soru özellikle RxJava en ilgilidir Akışkan ziyade genel olarak Tanrı nesnelerden daha sınıfına.]



1
@gnat Kesinlikle ilişkilidir, ancak bu bir kopya değildir. Bu soru jenerik oldu ve benim sorum özellikle RxJava en ilgilidir Akışkan sınıfa.
skomisa

@skomisa Ardından, başlığınızı sorunuza göre düzeltin.
Euphoric

@Euphoric Point alındı.
skomisa

1
Bu soru çok ilginç ve temelli. Ancak, daha az sübjektif bir stil benimsemek için hafifçe yeniden sarmayı öneririm (muhtemelen ilk şok ;-) nedeniyle)
Christophe

Yanıtlar:


14

TP; DL

Java'nın C # ile karşılaştırıldığında dil özelliklerinin olmaması ve keşfedilebilirlik hususları, kaynak ve ara operatörleri büyük sınıflara koymamızı sağladı.

tasarlamak

Orijinal Rx.NET, iki önemli özelliğe sahip C # 3.0'da geliştirildi: genişletme yöntemleri ve kısmi sınıflar. Birincisi, daha sonra bu hedef türünün bir parçası gibi görünen diğer türlerde örnek yöntemleri tanımlamanıza izin verirken, kısmi sınıflar büyük sınıfları birden çok dosyaya bölmenize izin verir.

Bu özelliklerin hiçbiri Java'da yoktu veya mevcut değildi, bu nedenle, RxJava'yı yeterince kullanışlı hale getirmenin bir yolunu bulmak zorundaydık.

RxJava'da iki tür operatör vardır: statik fabrika yöntemleri ile temsil edilen kaynak benzeri ve örnek yöntemleri ile temsil edilen ara benzeri. Birincisi herhangi bir sınıfta yaşayabilirdi ve böylece birden fazla hizmet sınıfına dağıtılmış olabilirler. İkincisi üzerinde çalışmak için bir örnek gerekir. Kavram olarak, bunların tümü, birinci parametre olarak akış yukarı olan statik yöntemlerle ifade edilebilir.

Bununla birlikte, uygulamada, birden fazla giriş sınıfına sahip olmak, yeni kullanıcılar tarafından özellik keşfini zahmetli hale getirir (unutmayın, RxJava, Java'ya yeni bir kavram ve programlama paradigması getirmek zorunda kaldı) ve bu ara operatörlerin bir kabus kullanması. Bu nedenle, orijinal ekip akıcı API tasarımı olarak adlandırıldı: tüm statik ve örnek yöntemlerini barındıran ve tek başına bir kaynak veya işleme aşamasını temsil eden bir sınıf.

Hataların birinci sınıf doğası, eşzamanlılık desteği ve fonksiyonel doğası nedeniyle, reaktif akışla ilgili her türlü kaynak ve dönüşümle ortaya çıkabilir. Kütüphane (ve konsept) Rx.NET günlerinden bu yana geliştikçe, giderek daha fazla standart operatör eklendi ve bu da doğası gereği yöntem sayısını arttırdı. Bu iki olağan şikayete yol açar:

  • Neden bu kadar çok yöntem var?
  • Neden benim özel sorunumu çözen bir X yöntemi yok?

Reaktif operatörler yazmak, yıllar boyunca pek çok insanın ustalaşması zor bir iştir; çoğu tipik kütüphane kullanıcısı kendi başlarına operatör oluşturamaz (ve genellikle denemeleri gerekmez). Bu, zaman zaman standart sete başka operatörler eklediğimiz anlamına gelir. Buna karşılık, çok spesifik olması ya da sadece kendi ağırlığını kaldıramayan bir kolaylık nedeniyle daha birçok operatörü reddettik.

RxJava tasarımının organik olarak büyüdüğünü ve SOLID gibi belirli tasarım prensipleri boyunca değil. Çoğunlukla akıcı API'sinin kullanımı ve hissi tarafından yönlendirilir.

Rx.NET ile diğer ilişkiler

2013'ün sonlarında RxJava geliştirmesine katıldım. Anlayabildiğim kadarıyla, ilk 0.x sürümleri büyük ölçüde Rx.NET Observableoperatörlerinin adlarının ve imzalarının yanı sıra birkaç mimari kararın yeniden kullanıldığı bir kara kutu yeniden uygulamasıydı . Bu, Rx.NET operatörlerinin yaklaşık% 20'sini içeriyordu. O zamanki ana zorluk C # ve Java arasındaki dil ve platform farklılıklarının çözülmesiydi. Büyük bir çaba ile, Rx.NET'in kaynak koduna bakmadan birçok operatörü uygulamayı başardık ve daha karmaşık olanları taşıdık.

Bu anlamda, RxJava 0.19'a kadar, ObservableRx.NET'lere IObservableve onun eşlik eden Observableuzatma yöntemlerine eşdeğerdi . Ancak, sözde geri basınç sorunu ortaya çıktı ve RxJava 0.20, protokol ve mimari düzeyde Rx.NET'ten ayrılmaya başladı. Mevcut operatörler genişletildi, birçoğu baskıya karşı duyarlı hale geldi ve yeni tipler sunduk: Singleve Completable1.x döneminde, Rx.NET'te şu anki benzerleri yok.

Karşı basınç farkındalığı işleri önemli ölçüde karmaşıklaştırır ve 1.x Observablebunu sonradan düşünülen bir şey olarak aldı. İkili uyumluluğa olan bağlılığı yemin ettik, bu nedenle protokolü ve API'yi değiştirmek çoğunlukla mümkün değildi.

Rx.NET'in mimarisinde başka bir sorun daha vardı: eşzamanlı iptal mümkün değildir çünkü bunu yapmak için, Disposableişleç yürütülmeye başlamadan önce birinin döndürülmesi gerekir. Ancak, gibi kaynaklar Rangeistekli ve bitene kadar geri dönmez. Bu sorun, bir enjekte ederek çözülebilir Disposableiçine Observeryerine bir tane dönen subscribe().

RxJava 2.x bu hatlar boyunca sıfırdan yeniden tasarlandı ve yeniden uygulandı . FlowableAynı operatör setini sunan ayrı, basınca duyarlı bir tipimiz var Observable. Observablekarşı basıncı desteklemez ve bir şekilde Rx.NET'lerle eşdeğerdir Observable. Dahili olarak, tüm reaktif tipler iptal kollarını tüketicilerine enjekte ederek senkronizasyonun verimli bir şekilde çalışmasını sağlar.


10

Kütüphaneye aşina olmadığımı itiraf ederken, söz konusu Flowable sınıfına bir göz attım ve bir tür hub gibi davranıyor gibi görünüyor. Başka bir deyişle, girişleri doğrulamak ve çağrıları projeye göre dağıtmak için tasarlanmış bir sınıftır.

Bu nedenle bu sınıf bir Tanrı nesnesi olarak düşünülmez çünkü Tanrı nesnesi her şeyi yapmaya çalışan bir nesnedir. Bu mantık açısından çok az şey yapar. Tek sorumluluk açısından, sınıfın tek işinin kütüphane genelinde çalışma yetkisi verdiği söylenebilir.

Doğal olarak böyle bir Flowablesınıf, bu bağlamda bir sınıfa gereksinim duyabileceğiniz her olası görev için bir yöntem gerektirir . Javascript'te jQuery kütüphanesi ile aynı desen görüyorsunuz, burada değişken $, jQuery durumunda da kütüphanede çağrı yapmak için gerekli tüm işlevlere ve değişkenlere sahip, kod sadece yetki verilmiş değil, aynı zamanda iyi bir mantık içinde çalıştırılır.

Bence böyle bir sınıf oluşturmaya dikkat etmelisiniz, ancak geliştirici sadece bir merkez olduğunu hatırladığı sürece yeri vardır ve bu nedenle yavaş yavaş bir tanrı nesnesine dönüşmez.


2
Hem yararlı hem de aydınlatıcı olan cevabınızın kabulünü ortadan kaldırmak için özür dileriz, ancak akarnokd'un sonraki yanıtı RxJava ekibindeki birinden geldi!
skomisa

@skomisa Benim kendi sorum olsaydı daha fazla bir şey için umut olabilir! Alınan suç yok! :)
Neil

7

NET'in RX eşdeğer etmek Flowableolduğunu gözlemlenebilir . Ayrıca tüm bu yöntemlere sahiptir, ancak statik ve uzatma yöntemleri olarak kullanılabilirler . RX'in ana noktası, kompozisyonun akıcı arayüz kullanılarak yazılmasıdır .

Ancak Java'nın akıcı bir arayüze sahip olması için, statik yöntemlerin iyi oluşturmayacağı ve statik yöntemleri kompostlanabilir hale getirmek için uzatma yöntemlerine sahip olmadığı için bu yöntemlerin örnek yöntemler olması gerekir. Yani pratikte, akıcı arayüz sözdizimini kullanmamanız durumunda, tüm bu yöntemler statik yöntemler haline getirilebilir.


3
Akıcı arayüz kavramı, IMHO, dil sınırlamaları için bir çözümdür. Etkili bir şekilde, Java'nın üstünde bir sınıf kullanarak bir dil oluşturuyorsunuz. Basit bir programlama dilinde bile kaç özelliğe sahip olduğunu ve tüm aşırı yüklenmiş varyantları saymadığınızı düşünüyorsanız, bu birçok yöntemle nasıl sonuçlandığınızı görmek oldukça kolay hale gelir. Java 8'in fonksiyonel özellikleri, bu tür bir tasarıma yol açan birçok konuyu ele alabilir ve Kotlin gibi çağdaş diller, yöntem zincirine ihtiyaç duymadan aynı tür avantajlardan yararlanabilmek için hareket eder.
JimmyJames

Mesajınız sayesinde daha derin kazdık ve .NET'in RX's Observable'ı RxJava'nın Observable'a benziyor, bu yüzden sorumun öncülü yanlıştı. OP'yi buna göre güncelledim. Ayrıca, RxJava'nın Akışkan ≈ (Gözlenebilir + geri basıncı paralelleştirme ve işleme için birkaç ekstra yöntem).
skomisa

@skomisa Java's Observable'ın da yüzlerce yöntemi var. Böylece ikisini karşılaştırabilirsiniz. Ancak en büyük fark, .NET'in Gözlenebilir'in statik ve tüm yöntemlerin statik olmasıdır. Java olmasa da. Ve bu çok büyük bir fark. Ancak pratikte aynı şekilde davranırlar.
Euphoric
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.