Örnek alanlarına bağlı olmayan yöntemler statik hale getirilsin mi?


19

Son zamanlarda Groovy'de bir Java projesi için bir entegrasyon testi çerçevesi için programlamaya başladım. Intellij IDEA'yı Groovy eklentisiyle kullanıyorum ve statik olmayan ve örnek alanlarına bağlı olmayan tüm yöntemler için bir uyarı olarak gördüğüme şaşırdım. Ancak Java'da bu bir sorun değildir (en azından IDE'nin bakış açısından).

Herhangi bir örnek alanına bağımlı olmayan tüm yöntemler statik işlevlere dönüştürülmeli mi? Doğruysa, bu Groovy'ye özgü mü yoksa genel olarak OOP için kullanılabilir mi? Ve neden?


Bu yöntemler başka örnek yöntemleri olarak mı adlandırılır? Yoksa kelimenin tam anlamıyla o sınıfın bir nesnesiyle hiçbir ilgisi yok mu? Bir örnek verebilir misin?
Ray Toal

Yanıtlar:


26

IDEA'nın Java için de bu denetime sahip olduğuna dikkat edin, Yöntem 'statik' olabilir ,

Bu denetim, güvenli bir şekilde statik hale getirilebilecek yöntemleri bildirir. Bir yöntem, sınıfının statik olmayan yöntemlerinden ve statik olmayan alanlarından herhangi birine başvurmazsa ve bir alt sınıfta geçersiz kılınmazsa statik olabilir ...

Ancak Java kodu için bu denetim varsayılan olarak kapalıdır (programcı kendi takdirine bağlı olarak açabilir). Bunun nedeni büyük olasılıkla bu tür bir denetimin geçerliliğine / yararlılığına birkaç oldukça yetkili kaynağa dayanarak itiraz edilebilir.

Başlangıç ​​olarak, resmi Java öğreticisi yöntemlerin ne zaman statik olması gerektiği konusunda oldukça kısıtlayıcıdır:

Statik yöntemler için yaygın bir kullanım, statik alanlara erişmektir.

Yukarıda verildiği gibi, varsayılan olarak bahsedilen denetimin açılmasının Java'da önerilen statik değiştiricinin kullanılmasına uygun olmadığı iddia edilebilir.

Ayrıca, bu teftişin arkasında yatan fikirleri kullanma ya da cesaretini kırma konusunda mantıklı bir yaklaşım öneren başka kaynaklar da var.

Örneğin, Java World makalesine bakın - Mr. Happy Object statik yöntemleri öğretir :

Örnek durumdan bağımsız herhangi bir yöntem, statik olarak bildirilmek için adaydır.

"Statik olarak ilan edilmek için aday" diyorum. Önceki örnekte bile hiçbir şey sizi instances()statik olarak bildirmeye zorlamaz. Statik olarak bildirmek, yöntemi çağırmak için bir örneğe ihtiyacınız olmadığından aramayı daha kolay hale getirir. Bazen, örnek durumuna bağlı görünmeyen yöntemleriniz olabilir. Bu yöntemleri statik yapmak istemeyebilirsiniz. Aslında, muhtemelen yalnızca örnek olmadan erişmeniz gerekiyorsa statik olarak bildirmek isteyeceksiniz.

Dahası, böyle bir yöntemi statik olarak bildirebilmenize rağmen, tasarımınıza müdahale ettiği kalıtım sorunları nedeniyle istemeyebilirsiniz. Karşılaşacağınız bazı sorunları görmek için "Etkili Nesneye Dayalı Tasarım" a göz atın ...

Google test blogundaki bir makale, Statik Yöntemlerin Ahit Edilebilirlik İçin Ölüm olduğunu iddia etmek kadar ileri gider :

Zihinsel bir egzersiz yapalım. Uygulamanızın statik yöntemlerden başka bir şey olmadığını varsayalım. (Evet, böyle bir kod yazmak mümkündür, buna prosedürel programlama denir.) Şimdi bu uygulamanın çağrı grafiğini hayal edin. Bir yaprak yöntemini çalıştırmayı denerseniz, durumunu ayarlama ve tüm köşe durumlarını iddia etme konusunda hiçbir sorununuz olmaz. Bunun nedeni, bir yaprak yönteminin başka çağrı yapmamasıdır. Yapraklardan uzaklaştıkça ve kök main()yöntemine yaklaştıkça , testinizde durumu ayarlamak zorlaşır ve bir şeyler iddia etmek zorlaşır. Birçok şeyin iddia edilmesi imkansız hale gelecektir. Testleriniz giderek büyüyecek. Bir kez ulaştığınızdamain()Artık bir birim testiniz yok (üniteniz tüm uygulama olduğu için) artık bir senaryo testiniz var. Test etmeye çalıştığınız uygulamanın bir kelime işlemci olduğunu düşünün. Ana yöntemden iddia edebileceğiniz çok şey yok ...

Bazen statik yöntemler diğer nesneler için bir fabrika olabilir. Bu, test problemini daha da şiddetlendirir. Testlerde, önemli bağımlılıkları alaylarla değiştiren nesneleri farklı şekilde kablolayabileceğimize güveniyoruz. Bir newoperatör çağrıldıktan sonra yöntemi bir alt sınıfla geçersiz kılamayız. Böyle bir statik fabrikanın arayanı, statik fabrika yönteminin ürettiği beton sınıflarına kalıcı olarak bağlıdır. Başka bir deyişle, statik yöntemin hasarı, statik yöntemin kendisinin çok ötesindedir. Nesne grafik kablolama ve yapı kodunu statik yönteme eklemek çok kötüdür, çünkü nesne grafik kablolama, işleri test etmek için şeyleri nasıl izole ettiğimizdir ...


Yukarıda verilen denetimin Java için varsayılan olarak kapalı olduğu sadece doğal görünüyor.

IDE geliştiricileri , yaygın olarak tanınan önerilere ve en iyi uygulamalara karşı varsayılan olarak ayarlamanın neden bu kadar önemli olduğunu düşündüklerini açıklamakta gerçekten zorlanacaklardı.

Groovy için işler oldukça farklı. Yukarıda listelenen argümanların hiçbiri, özellikle Javalobby'deki Groovy makalesinde Statik Yöntemleri Mocking'te açıklandığı gibi, özellikle test edilebilirlikle ilgili olanlar geçerli değildir:

Test ettiğiniz Groovy sınıfı, başka bir Groovy sınıfında statik bir yöntem çağırıyorsa, yöntemleri, yapıcıları, özellikleri ve statik yöntemleri dinamik olarak eklemenizi sağlayan ExpandoMetaClass'ı kullanabilirsiniz ...

Bu fark, büyük olasılıkla söz konusu inceleme için varsayılan ayarın Groovy'de zıt olması muhtemeldir. Java'da varsayılan "on" kullanıcı karışıklığı kaynağı olsa da, Groovy'de zıt bir ayar IDE kullanıcılarını karıştırabilir.

"Hey yöntem örnek alanları kullanmıyor, neden beni bu konuda uyarmadınız?" Bu sorunun Java için (yukarıda açıklandığı gibi) cevaplanması kolay olurdu, ancak Groovy için sadece zorlayıcı bir açıklama yoktur.


Bu arada, ReSharper (JetBrains tarafından C # / Visual Studio için yapılmıştır) aynı şeyi önerir
Konrad Morawski

6
Yan etkileri olan ve olmayan statik yöntemler arasında önemli bir ayrım vardır. Google alıntısı gerçekten birincisine hitap ediyor.
assylias

@assylias Öyle, ama aynı zamanda fabrika yöntemlerinin testi nasıl zorlaştırabileceğini de tartışıyor (çünkü uygulamadaki bağımlılıkları sıkıca birleştiriyor). Bağımlılık enjeksiyon çerçevesinin kullanılması bunun için en iyi çözümlerden biridir ve diğer birçok sorunu da çözer.
Per Lundberg

5

Bunun performans üzerinde fark edilebilir bir etki yaratacağını hayal etmek zor. Onları elde etmek için görebildiğim tek fayda, staticörnek durumun etkilenmediğine dair görsel bir gösterge sağlamasıdır. Başka bir deyişle, kaynak kodu okuyan kişiye, sadece orada olması nedeniyle, bu yöntem hakkında "ilginç" bir şey söyler. Asıl soru şu, açıklığa kavuşuyor mu yoksa karıştırıyor mu? "Bu yöntem neden statiktir? Bu bir fabrika yöntemidir? Bir nesne örneği gerekmeden çağırma özelliği var mı?"

Buna ek olarak, bazı insanlar statik yöntemleri sevmezler, çünkü onlarla alay edemeyeceğinizi iddia ederler ve bu nedenle test edilemezler veya bu çizgiler boyunca bir şey değildir. Kesinlikle, örneğin bir fabrika yöntemi sağlamak gibi olağan nedenlerden herhangi biri için statik yapıyorsanız, o zaman ben bunun için varım. Sadece örnek duruma dokunmadıkları için yöntemleri statik hale getirmenin bir zorunluluk olduğundan emin değilim.


5
(Java içinde) statik bir yöntemin geçersiz kılınamayacağını düşünün. Genellikle sorun olmasa da, bazı alt sınıflar daha sonra bu uygulamayı değiştiremez. Bu, statik bir yöntemin doğru cevap değil tasarım düşüncelerinin bir parçası olduğu anlamına gelmez.

2
@ user40980 düşünmeye değer, doğru, ama aynı zamanda kalıtımın sıklıkla yanlış kullanılan beceriksiz bir araç olabileceğini ve bazı belirgin figürlerin tüm sınıfların finalmiras göz önünde bulundurularak veya özel olarak tasarlanması gerektiğini savunuyor .
sara

3

Bence olası yeniden düzenlemenin fark edilmesini sağlamak .

Yöntem statik hale getirildikten sonra , örneğin bir birlik sınıfına sınıftan çıkarılabileceği açıktır .

Ayrıca, parametrelerinden birinin örnek yöntemine dönüştürmek kolaydır, genellikle kodun olması gereken yer burasıdır.


-1

Bazı arabirimleri uygulayan durumsuz sınıflara sahip olabileceğinizi unutmayın (örneğin java.lang.Runnable, yöntemlerini statik hale getiremezsiniz. Bazı desenler (örn. Strateji), birkaç yöntem bile içeren durumsuz nesneler üretebilir.

Statik, singletonların ilk kuzenleridir. Daha sonraki bir aşamada statikten statik olmayan duruma geçmek gerçekten zor olacaktır - bu nedenle durum eklemeniz gerektiğinde statik değişkenleri tanıtmaya başlayabilirsiniz.


bu sorulan soruya nasıl cevap veriyor?
gnat

1
hiçbir eyaletten bir eyalete gitmek neden zor? Bunun tam tersi olduğunu söyleyebilirim. saf bir şeyi kontamine etmek, kontamine olmuş bir şeyi arındırmaktan daha kolaydır.
sara
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.