Soru Oyun! çerçeve bir statiği kullanır


Waaah, Oyun! çerçeve çok fazla statik yöntem var. Okula gittiğim yere söylendi asla herhangi bir statiği kullanmak için, henüz Oyna! yarın yokmuş gibi kullanır. Bu bir şekilde tamam mı? Öyleyse neden?

Biz (7 kişi ve ben) oyunu kullanmayı planlıyoruz! Bir web uygulaması içeren bir proje için çerçeve. Play ile yapmaya karar verdik! Yapmak çok eğlenceli gözüküyor, hepimiz zaten Java'yı biliyoruz ve ödev oldukça zor, bu yüzden farklı bir dilde nasıl program yapacağımızı öğrenmek yerine gerçek ödeve odaklanmak istedik.

Ancak her zaman söylendi, ASLA ASLA geliştirdiğimiz herhangi bir Java programında 'static' kullanmak, ancak Play'e baktığımda! ... Şey ... yöntemlerin yaklaşık yarısı statik. </ Abartı>

En azından, projemizi programlamak için singleton nesnelerini kullanabiliriz (örneğin Scala'yı kullanarak, örneğin ^^), ancak gerçekte kaç tane statiğin gerçekte olduğu konusunda oldukça endişeliyim.

Bu konuda endişelenmeli miyim? Oyunun yolu muydu? geliştiriciler, tüm bu statiklerin bir sorun yaratmayacak şekilde programlandığını programladılar mı?

(Örneğin, bu konu Her ne pahasına olursa olsun statik üyelerden kaçınılması gerektiğine dair bir rant vardır.)


76
2018-03-04 11:06


Menşei


Uh ... Muhtemelen profesörünüze ya da her kimseye sormalısınız. Ayrıca, dünyanın geri kalanı için iyi ve kötü programlama pratiği hakkında aynı fikirlere sahip olmamanız doğaldır, bu yüzden fikre alıştırın. :) - unwind
@Saew statiğin kullanılmasına izin verilmemesine rağmen, "ASLA ASLA statik kullanmayın" bir abartıdır - Suraj Chandran
<exaggeration> etiketi görünmüyor. :) - Nishant
İşte bu, profesörümüz bir OO-purist. Bizi her zaman statics kullanmanın tehlikeleri konusunda uyarıyor ve neden kullanmakta olduğumuzdan ve sonuçların olmasından korkmadığımızdan iyi bir açıklama sağlayamadıkça statiklerini kullanmak için kafalarımıza sahip olacak. - Saew
@Hishant Şimdi öyle :) - jensgram


Cevaplar:


Oynat, yalnızca mantıklı olduğunda statik yöntemler kullanır:

  • kontrolör katmanında, çünkü kontrolörler nesne yönelimli değildir. Kontrolörler, HTTP dünyası (yani durum bilgisi olmayan ve istek / yanıt temelli) ile tamamen nesne odaklı Model katmanı arasında mapper işlevi görür.
  • herhangi bir özel örneğe bağlı olmayan findAll (), count (), create () gibi fabrika yöntemleri için model katmanında
  • Bazı play.libs. * tamamen yardımcı işlevler sağlayan sınıflar

95
2018-03-04 12:31



Ek olarak, asıl sorun statik olmayan yöntemler statik üyelerdir. Oyunda sadece statik üyeler olarak threadlocals vardır. - niels
Kullanımı statik validation üye  (görmek örnek) ile birlikte ThreadLocal gösterir, statik her durumda uygun değildir. - deamon
Ben DI çerçevesinden enjekte edilen bağımlılıkları olan denetleyicilere sahip olacağım. DI'yi statik nesneleri kullanarak nasıl uygularsınız? - ripper234
@Guillaume Benimle aynı fikirde değilim, Play, Java yazmanın en kötü uygulamalarını gösteriyor ve kullanmak için herhangi bir mazeret olmamalı. staticJava kodunda, hiç. Çekilebilirlik statikler tarafından belirtilmemiş, tam tersi statik belirtiler paylaşılan durum ki iddia ettiğiniz şeyden neredeyse tam tersi. Daha sonra, statik yöntemlerin, tanımlandıkları sınıfa bile eşit olmadıkları için, yanlış örnekte statik yöntem çağrılması gibi, yansıtma eğlenceli şeyleri vardır. staticJava'da çok büyük bir kod kokusu var ve eğer amacınız modern Java yazmaksa hiç olmamalı. - Esko
@Esko Kesinlikle size katılıyorum, Oyun scala'da değerli olabilir, ancak Java'da kötü uygulamaların bir listesini özetlemektedir. - Snicolas


Oynatma çerçevesi, statiğin ne zaman kullanıldığının iyi bir kanıtı değildir ve öğretmeninizin yanlış olduğunu kanıtlamaz. Play, aldatmacadır, Java dilinin dışındaki statics sorunlarını çözer.

Temel sorun, birden çok HTTP isteğini paralel olarak işlemeniz ve statik alanların "genel" olması. Bu nedenle, belirli şeyler için iş parçacığı başına bir örneğe (veya daha da iyisi, her HTTP isteği için bir örneğe) gereksinim duyacaksınız, ancak bu şeylerin bazıları Play'deki statik yöntemlerle döndürülüyor. Bu işe yarıyor çünkü Play! kullanımları ThreadLocal-sıkça, ve bu yüzden Java dili dışındaki statics problemlerini çözer. Ama bu her şey değil. Bazıları denetleyici yöntemlerinin haklı olarak statik olduğunu söylüyor. Elbette, ancak düz Java'da bu durum rahatsızlık verici olur, çünkü istediğiniz gibi bir önek olmadan isteğe özel verilere erişemezsiniz. req. içinde req.sessionve sonra hala almak zorundasın req Bir yerden, daha fazla güçlük çeken statik denetleyici yönteminin bir parametresi gibi. Yine de Play'de doğrudan yazabilirsiniz session ve onlar sadece statik alanlardır. Çünkü Play, tüm bu statik alan referanslarını daha akıllı bir şeye dönüştürmek için bytecode enstrümantasyonunu kullanıyor. Yine, Java dili dışında bir çözüm. Bunlar sonunda statik alanlar değil.

Yani, genel olarak, nihai olmayan statikten kaçının. Oyun sizin için büyüyü yapar, bu yüzden onları bu olaydan korkmayın.


34
2017-08-04 19:15





Çok kısa bir bakış açısından, bunun bir anlamı olduğunu söyleyebilirim: web istekleri vatansız, yani olduğu isteği almak için hiçbir nesne (= yöntem). Böylece, "/ articles / archive? Date = 08/01/08 & page = 2" gibi bir URI'yi statik bir yönteme eşlemek archive() Açıkçası, uygulama sınıfınız mantıklı.


15
2018-03-04 11:12





DÜZENLE Şimdi Play 2.4'te, enjeksiyon otomatik olarak yapılır. Dosyada denetleyici yolunun başında @ ekleyerek routes hile yapacak:

GET     /                  @controllers.Application.index()

Eski sürümlerde (2.1'den 2.3'e kadar), Global sınıfta getControllerInstance'ı geçersiz kılmanız gerekir. Documentantion.


8
2017-12-14 01:59





Programlamada olduğu gibi asla asla doğru cevap değildir. Aynen her zaman. Her zaman istisnalar vardır ve doğru cevap her zaman 'bağlıdır'.

Saf OO'da (ki hepimiz için) statikler için çok az yer olduğu doğru. Ama aynı zamanda bazen mantıklı oldukları da doğru.

Klasik örnek, faydalı yöntemlerdir. Tabi, eğer sadece ekleyebilirsek daha iyi olur. abs() Tamsayıya yöntem. Ama yapamayız; bu yüzden sıkıştık Math.abs(int i).

Örneğin kendisi ile hiçbir ilgisi olmadığı zaman bir yöntem statik yapmak için doğru olduğunu düşünüyorum. Örneğin, bir sınıfta Personİnsanların listesini alan ve bugün doğum günü olan insanların sayısını döndüren bir yönteminiz olabilir. Belki de bunu hesaplamanın yapılması için gereken veriler özelse (OO'nun bir anlaması anlayacaktır;)), ancak bu yöntemin tek bir Kişi örneğiyle hiçbir ilişkisi olmadığı sürece bunu yapabilirsiniz.

Başka bir şey iç sınıflar. İçerdiği türle ilişkinize ihtiyaç duymazsanız, genellikle onları statik yapmak istersiniz.

hiç görmedim Oyun! ama bunun% 50'den fazlasının statik olduğunu söylerseniz, muhtemelen kötü tasarlanmış olduğunu tahmin ediyorum. Bu bir istisna değil; bir çok çerçeve var. Seni indirmesine izin verme. Kesinlikle ondan öğrenme!
Ama işe yarıyorsa, yine de kullanabilirsiniz.


5
2018-03-04 12:11



Oyun kötü bir şekilde tasarlanmamıştır, ancak çoğu Java kütüphanesinin tasarlanma biçiminden bir sapmadır. - Marcus Downing


Asıl sorun, statik yöntemlerin, yalnızca statik statik (ler) yoluyla, statik yöntemlerin, uygulamanın geri kalanıyla (ortak çalışanlarını içeren) geri buluşması gereken "statik yapıştırma" ile sonuçlanan, diğer statik yöntemlere ve alanlara erişimi olmasıdır. , bu da bükülmezliğe yol açar.

Yasal Uyarı: 'Oynamak!' Hakkında fazla bir şey bilmiyorum.


4
2018-03-04 11:41





Statik kontrolör yöntemleri kesinlikle Play ile ilgili bir endişe alanı! çerçeve ve bazı testler yaptıktan sonra, Play yapmamanın ana sebebi! projelerde Bunu, nerede Play'in bulunduğu FOSS projelerinde görebilirsiniz! kullanıldı. Denetleyici testi çok az veya yok. Statik yöntemlerle DI neden zor olur. Burada, Play'den ASP.NET MVC ile daha fazla zaman geçirmeleri gereken yer burası! zaten biraz ilham alıyor.

Genellikle böyle bir kurucunuz var:

public HomeController( IService service ) {
   _service = service;
}
public Index() {
   var data = _service.getData();
   return View( data );
}

Ardından, IService uygulamasını Controller'a enjekte etmek için DI kullanırsınız. Testlerinizdeki nokta, Denetleyiciyi çalıştırmadan önce IService'i başlatabilir ve daha sonra, yeni ürettiğiniz IService'i temel alarak sonucu test edebilirsiniz.

Oyunda bu çok zor olur. Böylece Denetleyici birim testi zorlaşır. Bu benim için önemli bir problem. Bu nedenle, Play'den başka bir çerçeveye bakmaya eğilimliydim! Java dünyasında. Heck, neden orijinaliyle gitmiyorsun ve sadece JRuby'yi kullanmıyorsun?


4
2017-10-29 12:36





Oyundaki statik yöntem esas olarak denetleyicilerin eylem yöntemlerinde kullanılır. Bu yöntemler, yalnızca gerekli verileri modelden almak ve bunları görüntülemeye maruz bırakmak içindir.

Her bir olası http isteği ile bir şekilde örtüşüyorlar ve tıpkı http isteklerinin tamamen vatansız olduğu gibi.

Yapısal programlamada bir yandan prosedürler, öte yandan da değişkenler vardır, fakat OOP paradigmasında prosedürleri ve değişkenleri bir bütün olarak ele alırsınız.

Yani, örnek yöntemlere (yordamlara) ve örnek değişkenlerine sahip ve bunlarla itiraz edebilirsiniz.

Fakat denetleyici eylemleri durumsuzdur, yani tüm değişkenleri isteğe göre alırlar (belki de önbellekten de olabilirler, ancak bu durumda son olarak istekten gelen bir tür oturum kimliği gerekir). Kontrolör eylemleri tıpkı stateles prosedürleri gibidir ve bu yüzden modellerin yaptığı gibi OOP paradigmasına uymazlar.


3
2018-03-05 05:12





Sanırım, en azından, singleton nesnelerini kullanabiliriz

Java'daki Singleton, tüm statikleri kullanmaktan çok fark yaratmaz. Devlet olarak da depolanacak çok şey yok. Bunun için endişelenmemelisin.

Bu konuda endişelenmeli miyim? Oyunun yolu muydu? geliştiriciler, tüm bu statiklerin bir sorun yaratmayacak şekilde programlandığını programladılar mı?

Olmaz. Aslında, her şey yolunda.


2
2018-03-04 11:23



Tamam .. sanırım. Benim vicdanım hala statik kullanmak için bana nags, ama ben bu kez görmezden geleceğim :) - Saew
Singleton'ları klasiklerle karşılaştırmak için +1 - Joeri Hendrickx
-1 Çünkü statik olmayan yöntemlerle singletonda kalıtım ve polimorfizmi uygulayabiliriz, fakat statik dünyasında OOP'un bu faydalarını KULLANAMAMIZ. Yani neredeyse aynı değil. - ses
Tektonlar için iyi dil desteği yerine statiğin olması, muhtemelen Java dilinde en büyük kusurdur. Scala'nın arkadaşı-nesne sistemi, bu küçük değişikliğin nasıl büyük faydalara sahip olabileceğine dair bir durum çalışmasıdır. Uygulamayı gerçek dünyada hiçbir zaman takas etmese bile, bir uygulamayı sınamada takas etmek neredeyse her zaman faydalı olur. Birkaç istisna dışında profesöre şiddetle katılıyorum. Tek kişilik yapmak o kadar da zor değil. - Sarah G


Ayrıca oyundaki statik yöntemlerin sayısı beni şaşırttı, ama neden iyi çalışıyorsa ...

Aslında öğretmeninize katılmıyorum.

Bir nesnenin bir durumu yoksa (örn. Global değişkenler), ancak yalnızca örnek yöntemler içerirse, statik yöntemlerden ziyade bir nesneyi kullanmanın yararı yoktur. Daha sonra bir durum eklemeyi planlıyorsanız (paylaşılmaması gereken durum) veya bir arabirim kullanıyorsanız ve uygulamayı kolayca değiştirmek istiyorsanız, statik yöntemleri kullanmak daha kolaydır ...

JDK'nın kendisi, apache commons veya birçok framework statik yöntemler içerir:

  • StringUtils
  • Pattern.matches (normal ifade, giriş)

----------

Aslında sanırım JPA.java gibi sınıflar hakkında ne düşünüyorsun: https://github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPA.java

Sadece statik yöntemler kullanır ve statik bir hal alırlar. Bu garip olabilir, ama aslında benim için bir yöntem yerine bir nesne yerine statik bir bağlamda kullanılan tek birtonu kullanmak gibi. Asıl fark, her zaman getInstance () 'ı çağırmak zorunda kalmamanızdır.

Bunun kullanılabilirlik için tasarlandığına inanıyorum çünkü "getInstance" olarak adlandırmak kullanıcı dostu değildir ve her yerde (thread ile bağlantılı olarak) xml veya autowiring ile her yerde sessionFactory enjekte etmek yerine kolayca bir oturum elde edebilmek harikadır. ..

Profesörünüz belki de statik kullanmamanızı söyler çünkü doğru kullanmadığınız takdirde tasarımınız için tehlikeli olabilir. Ancak, çoğu durumda, statik yöntemleri tekil olarak değiştirmek, tasarımınızı daha iyi hale getirmez. Şimdi bir örnek yönteminde yöntemleri çağırsanız bile, nesneler hala sıkı bir şekilde birleştirilecektir ...

Bu yüzden belki de sıkı bir bağlantıyı önemsemediğiniz durumlar dışında statiğin kullanılmasından kaçınmak bir kural olmalıdır.

  • Bu durumda, JPA.xxx () yöntemlerini çağırdığınızda, kodunuzun çerçevenin JPA sınıfını çalması için sıkı bir şekilde eşleştirilir. Ama oyunun, bir çerçeveden diğerine, en azından biraz yeniden çalışma yapmadan kolayca geçiş yapabilmeniz için tasarlandığını düşünmüyorum ...

  • EJB3 spec veya bunun gibi şeyler ile büyük bir fark var: EJB3 varlık yöneticisinin yöntemleri statik olduğunda, sık sık HibernateEntityManager.xxx () veya ToplinkEntityManager.xxx () çağırarak uygulamaya kodunuzu zorlamak zorunda kalacaksınız. Bu durumda, ortak bir arayüz var (ve arayüzlerde statik yöntemler ekleyemiyoruz).

----------

  • Bu sınıf bir parçası değil. diğer özellikler çerçeveler.
  • JPA sınıfı sadece bir uygulama: tarafından yapılan oyun. Ve muhtemelen değiller ikincisi yapmayı planlamak.
  • Böylece bir bu Play sınıfına sıkı bağlantı, Play framework'ü kullanırken benim için iyi görünüyor.

1
2018-05-25 13:33