Sadece Statik yöntemler içeren *** Yardımcı veya *** Util sınıflarının kullanımı bir AntiPattern mi?


19

Genellikle Java'da veya herhangi bir dilde yardımcı veya util sınıflarıyla karşılaşıyorum. Bu yüzden kendime bunun bir çeşit Anti Desen olup olmadığını soruyordum ve bu tür sınıfların varlığı sadece bir Yazılımın tasarımında ve mimarisinde eksikliklerin olmamasıdır.

Genellikle bu sınıflar, birçok şey yapan sadece statik yöntemler kullanılarak sınırlandırılır. Ancak çoğunlukla bağlama bağımlı ve durumsaldır.

Benim sorum, bu tür statik yardımcı / util sınıfları hakkındaki görüşünüz nedir, çünkü avantaj elbette sadece sınıf adını kullanan hızlı çağrıdır.

Ve ne tür bir soyutlama seviyesinde bu tür sınıfları kullanmaktan kaçınırsınız?

Kanımca "statik" anahtar kelimesine yöntem için değil, bir sınıf (Java) bildirimi içinde izin verilmelidir. Bence bu şekilde kullanmak Java'da Procuedural- ve OO-Paradigmaları birleştirmek ve anahtar kelimenin yanlış kullanılmasını önlemek için iyi bir alternatif ve orta yol olabilir.

Cevaplar nedeniyle yapılan eklemeler:

İlk başta farklı paradigmaları birleştirmenin ve hatta makine veya vm derlenmiş kod içinde çalışma zamanı yorumlanmış komut dosyası dillerini kullanmanın tamamen yasal olduğunu düşünüyorum.

Deneyimlerim, bir projenin geliştirme sürecinde bu tür yardımcılar ve araçlar veya adı ne olursa olsun, kod tabanının modüler ve esnek olmak üzere tasarlanmış her unutulmuş köşesinde büyüyor ve kullanılıyor. Ve yeniden düzenleme yapmak veya tasarımı tekrar düşünmek için zaman eksikliği nedeniyle, sadece zaman içinde çok daha kötü hale getirirsiniz.

staticJava'dan kaldırılması gerektiğini düşünüyorum . Özellikle şimdi daha sofistike fonksiyonel dil öğelerinin kullanılmasının mümkün olduğu yerlerde.



Yardımcının bir sınıfı başlatması gerekmiyorsa, sorun değil. Sorun, yardımcı bir sınıfın somut bir uygulamasını başlatır ve o zaman bu arayüzü alay edememenizdir. Yardımcı bir arayüz veya soyut bir sınıftan geçerse bence sorun olmaz.
bobek

Prosedürel programlama yaptığını iddia ederseniz sorun yoktur. Nesne (yönelimli) programlama yaptığını iddia ederseniz değil.
Benekli

1
@Spotted: ve yalnızca nesne yönelimli programlama yaptığınızı iddia etmenin hiçbir iş değeri olmadığından, her zaman karışık paradigma programlama yapın ve boktan olun.
RemcoGerlich

@RemcoGerlich Kesinlikle. Demek istediğim, cevabın hangi programlama paradigmasını düşündüğünüzle ilgili olarak esas olarak "felsefi" olduğunu belirtmekti.
Benekli

Yanıtlar:


20

Java, ücretsiz işlevlerden yoksundur, böylece bunları bazı pro-forma sınıfına statik işlevler olarak koymak zorunda kalırsınız. Gerekli bir çözüm asla bir anti-desen değildir, ancak zarafetten yoksun olabilir.

Sonra, serbest fonksiyonlarda yanlış bir şey yok. Aslında, serbest fonksiyonların kullanılması, tüm kanlı ayrıntılar yerine yalnızca genel arayüze erişime sahip oldukları için kuplajı azaltır.

Tabii ki, serbest / statik işlevlerin kullanılması, mutasyona tabi paylaşılan, özellikle küresel durumun tehlikelerini hiçbir şekilde hafifletmez.


2
@TimothyTruckle Ya statiktirler ya da gereksizdirler thisve bir şeyin uygun şekilde somutlaştırılmasını gerektirirler
Caleth

6
@TimothyTruckle Çünkü bu Java. Diğer diller, yalnızca bir örnek yöntemi olmadığını bildirmek için onları bir sınıfa koymak zorunda kalmadan yüksüz işlevlere sahip olabilir . Ve bir noktada, sıkı bağlantıya sahip olmalısınız. İyi olup olmadığı tamamen yukarı söz konusu işlevi ne olduğunu yapar .
nvoigt

5
@TimothyTruckle Kesinlikle, devleti korumak "iyi değil" olmanın başlıca nedeni olurdu.
nvoigt

2
@nvoigt, bu cevabı açıkça belirterek büyük ölçüde geliştirilebileceğini düşünüyorum. Durumsal statikler kötüdür; vatansız olanlar iyidir. Gerçekten oldukça basit.
David Arno

3
@TimothyTruckle Bu sıkı bir bağlantı değil. Gevşek bağlantıyı tanımlıyorsunuz. Bu bağlamda sıkı bağlantı bir çeşit karşılıklı bağımlılık anlamına gelecektir. Tek yönlü bir bağımlılık bu şartı karşılamıyor.
JimmyJames

18

Statik yardımcı veya yardımcı işlevler, bazı yönergelere uymaları halinde bir anti desen değildir:

  1. Yan etkileri olmamalıdır

  2. Bu işlevlerin üzerinde çalıştığı sınıfa veya sınıflara ait olmayan uygulamaya özgü davranışlar için kullanılırlar

  3. Herhangi bir ortak devlet gerektirmezler

Yaygın kullanım durumları:

  • Tarihleri ​​uygulamaya özel bir şekilde biçimlendirme
  • Bir türü giriş olarak alan ve farklı bir tür döndüren işlevler.

Örneğin kullanıcılar üzerinde çalıştığım bir uygulamada faaliyetlerine yönelik günlük girişleri tutuyorum. Bir takip tarihi belirleyebilir ve bir etkinlik hatırlatıcısı indirebilirler. Bir günlük girdisi alıp bir .ics dosyası için ham metni döndürmek üzere statik bir yardımcı program sınıfı oluşturduk.

Herhangi bir ortak devlet gerektirmedi. Hiçbir durumu mutasyona uğratmadı ve bir iCal etkinliği oluşturmak kesinlikle uygulamaya özeldi ve dergi giriş sınıfına ait değildi.

Statik fonksiyonların veya yardımcı program sınıflarının yan etkileri varsa veya paylaşılan durum gerektiriyorsa, birim testi için taklit edilmesi zor olan bağlantıyı tanıdığı için bu kodu yeniden değerlendirmenizi tavsiye ederim.


4

Yaklaşımınıza bağlı olacaktır. Birçok uygulama, klasik zihniyetin aksine (üzerinde bulunduğunuz site paketlerinin çoğu dahil) daha işlevsel bir şekilde yazılmıştır.

Bu anlayışla, işçi sınıflarında statik yöntemler olarak birbirine bağlanabilen birçok faydalı yöntem olacaktır . Yalnızca verileri tutan ve aktarılan düz nesnelere daha yakın beslenirler / kullanılırlar.

Geçerli bir yaklaşımdır ve özellikle ölçekte çok iyi çalışabilir.


"Özellikle ölçekte çok iyi çalışabilir" Hayır. Statik erişimin neden olduğu sıkı bağlantı , proje büyüdükçe kısa süre içinde size engel olacaktır.
Timothy Truckle

@TimothyTruckle Agent.Save (obj) 'in obj.Save ()' den çok daha sıkı bağlandığını açıklayabilir misiniz? Ajan, bir sınıf örneği gibi statik yöntemler için bile DI / IoC referansı alabiliyor. Referans için Stack Exchange'in kendisi bu zihniyet içinde yazılmıştır ve bildiğim diğer tüm kaynaklardan daha az kaynağa sahip diğer ASP.Net uygulamalarından daha iyi ölçeklenmiştir.
Tracker1

"Agent.Save (obj) 'in obj.Save ()' den çok daha sıkı bir şekilde nasıl bağlandığını açıklayabilir misiniz?" Bu yanlış örnek. Doğru bir örnek Agent.Save(obj)vs. olacaktır agentInstance.Save(obj). İkincisi ile, kullanım koduna enjekte etme olanağına sahipsiniz agentInstance. Sonuç olarak enjekte edebilir herhangi bir çocuk sınıfını ait Agentfarklı "türleri" nden ile kullanarak kod og yeniden kullanımını verir de Agentderlemeye olmadan. Bu düşük bağlantıdır .
Timothy Truckle

Bence bu gerçekten birkaç şeye iniyor. Devlete ihtiyaç var mı, ne kadar esnek olması gerekiyor ve küresel / örnek duruma sahip olmak uygun mu? Karar vermek her geliştiriciye / mimara bağlıdır. Ben her şeyi bir bütün olarak anlamak daha zor hale senaryolar için karmaşıklık ekleyerek daha basit bir kod temeli tercih ederim. Düğüm / js hakkında sevdiğim şeylerden biri, basit / temiz kod yazabiliyorum ve yine DI / IoC spesifikasyonlarına yazılan kod olmadan test için enjekte edebiliyorum.
Tracker1Temmuz

2

Şahsen bu tür yardımcı sınıfların tek önemli bölümünün özel yapılmasıdır. Bunun yanı sıra - kesinlikle iyi bir fikirdir (az miktarda uygulanır).

Bunun hakkında düşündüğüm - eğer bir sınıf (veya fonksiyon) uygularken - böyle bir şey yardımcı olur ve bu uygulamayı daha açık hale getirirse, bu nasıl kötü olabilir? Ve OFTEN, verilerin belirli bir şekle sahip olmasına bağlı olan diğer algoritmalarla entegrasyona ve kullanımına izin vermek için bu tür özel yardımcı sınıfları tanımlamak için kritiktir.

'Yardımcı' olarak adlandırılıp adlandırılmayacağı küçük bir kişisel zevk meselesidir, ancak uygulamada yardımcı olduğunu ve daha geniş bir kitleye ilgisi / kullanımı olmadığını ifade eder. Eğer mantıklı olan buysa - devam et!


1
Genel hizmet sınıfları yine de yardımcı olabilir. Başbakan örnek: java.lang.Math.
amon

1

staticBir yanlış anlama dayalı olarak yardımcı sınıfların yaygınlığı . Sınıfları yalnızca static"yarar sınıfları" yöntemleriyle çağırmamız, POJO'larda ortak davranış yazılmasına izin verilmediği anlamına gelmez.

static yardımcı sınıflar üç nedenden dolayı anti-kalıptır:

  1. Bu yardımcı yöntemlere statik erişim bağımlılıkları gizler . Bu "yardımcı sınıflar" POJO'larsa, bağımlı bir sınıfın herhangi bir kullanıcısı için bağımlılığı bariz hale getirecek olan yapıcı parametreleri olarak onlara bağımlı bir sınıfa enjekte edebilirsiniz .

  2. Bu yardımcı yöntemlere statik erişim, sıkı bağlantıya neden olur . Bu , yardımcı yöntemleri kullanan kodun yeniden kullanılmasının zor olduğu ve (bir yan etki olarak) test edilmesi gerektiği anlamına gelir.

  3. Özellikle durumu koruyorlarsa bunlar sadece küresel değişkenlerdir . Ve umarım kimse küresel değişkenlerin iyi olduğunu iddia etmez ...

Statik yardımcı sınıfları, STUPID kodu anti deseninin bir parçasıdır .


Küresel devlet soruyla ilgisiz, - max630

OP şunu yazdı:

Ancak çoğunlukla bağlama bağımlı ve durumsaldır.

Statiğin statefull yapılar vardır küresel devletler.

her türlü kodu kullanabilir. - max630

Evet, sebebi. Ve neredeyse tüm uygulamaların bir çeşit küresel devlete ihtiyacı var .

Fakat küresel devlet ! = Küresel değişken .

Bağımlılık enjeksiyonu yoluyla OO teknikleriyle küresel durum oluşturabilirsiniz , ancak en alttaki küresel değişkenler olan durumsal statik yapılarla küresel durumdan kaçınamazsınız .


2
Küresel devlet soru ile ilgisi yoktur, her türlü kod onu kullanabilir.
max630

@ max630 lütfen güncellememi görün
Timothy Truckle

1
Birleştirme olmadan statik serbest fonksiyonlar kullanabilirsiniz. Func<Result, Args>Başka bir yerde başlatılan nesnelerin etrafından geçiyorsunuz.
Caleth

1
1) Genel olarak, uygulamanın gizlenmesinin uygun olan yerlerde iyi bir şey olduğunu düşünüyorum. 2) Her şeyi argüman / bağımlılık enjekte etmek gibi bir çeşit tasarım zamanı bağlantısı yaratır, kendinizi uzun bağımlılık zincirlerindeki imzaları değiştirmek için çok zaman harcamak zorunda bulduğunuzda bunu hissedebilirsiniz. Ve Logger'ınızı gerektiren her bir işleve veya diğer çapraz kesişen endişelere, bir argüman olarak, aciliyet gibi ... (Ama evet, düşük seviyeli testi daha zor hale getirebilir)
Alex

1
@Alex Öyleyse tam tersini söyleyeyim: Bir birim , aynı nedeni değiştirmek için herhangi bir kod grubudur (statik referanslı "yardımcı program" yöntemleri dahil) . Bu ünitenin içindeki her şey uygulama detayıdır . Başka bir şey bağımlılıktır ve ünite buna statik erişime sahip olmamalıdır.
Timothy Truckle
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.