Nesneleri statik yöntemlerle iletmek neden avantajlı olur?


9

Statik bir yöntem kullanmanın ve referansı bir nesneye yöntemi bir nesne üzerinde çağırmak yerine parametre olarak iletmenin avantajı nedir?

Ne demek istediğimi açıklığa kavuşturmak için aşağıdaki sınıfı düşünün:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

Statik bir yöntemle bu alternatif uygulama ile karşılaştırıldığında:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

Sorum sadece bu sınıfla sınırlı değil; bir nesneyi bir yönteme çağırmak yerine geçireceğiniz herhangi bir nokta ilgilendiğim şeydir. Bu hiç avantajlı mı? Öyleyse neden?


1
Aynı şeyi yapan iki yöntemle bir kod kokusu gibi geliyor. Statik yöntem basitçe diğer yönteme devredilirse, o zaman işe yaramaz, ancak mutlaka "kötü" olmaz
Nathan Merrill

13
@NathanMerrill Sanırım bu noktayı kaçırıyorsun. Birinci yöntem yerine ikinci yöntemi oluşturmanın ve kullanmanın tercih edilebileceği bir durum olup olmadığını soruyor .

@ Mego Sadece örnekte verilen yöntemler değil; Statik yöntemler kullanırken ve nesneleri geçerken herhangi bir an olup olmadığını soruyorum ben nesneler üzerinde yöntemleri çağırmak daha iyidir?
Addison Crump

Muhtemelen özellikle java mı istiyorsunuz?
enderland

3
Bence bu soru, nesne yönelimli kodun bir çeşit optimum olduğuna dair örtük bir varsayımda bulunuyor. Daha prosedürel veya işlevsel bir yaklaşım doğal olarak statik yöntemlerin kullanılmasına yol açacaktır. ... Bir statik ve bir örnek yöntemi arasındaki işlevselliği çoğaltmak oldukça saçma. Umarım bu sadece bir örnektir ve bahsettiğiniz gerçek kod sadece statiktir.
jpmc26

Yanıtlar:


34

Önemsiz bir örnek: geçirilen örnek yasal olarak boş olduğunda ve bunun (önemsiz) işlemeyi yönteme dahil etmek istediğinizde.


1
örnek: String.Compare C # (Java'da benzer bir şey olduğunu düşünüyorum)
edc65

Objects.equals () ve Objects.compare (), Java'daki örneklerdir - ancak orijinal sınıfta değildirler. En azından Java standart kitaplığında, Object gibi bir şey üzerinde bir örnek yöntemine sahip olmak, ancak bir Object s sınıfında statik bir yöntem olması yaygındır .
16'da daboross

20

Örneğinizde, örnek yöntemi açık bir kazanandır.

Genel durumda, statik bir yöntemin uygun olabileceği birkaç nedeni düşünebilirim:

  • Statik yöntemi başka bir sınıfa koymak istiyorsunuz, çünkü mantığı verilerden ayırmanın mantıklı olduğu bir durumunuz var (not: örneğiniz bunlardan biri değil).

  • İki veya daha fazla nesneyi geçiyorsunuz ve bunların eşit öneme sahip olduğunu vurgulamak istiyorsunuz.

  • null geçerli bir değerdir (9000 kullanıcısı tarafından açıklandığı gibi).


5

Nesnenin durumunu değiştiren yöntemleri statik yöntem yerine örnek yöntemler olarak dahil etmek akıllıca olacaktır .

Bununla birlikte pure, belirli doğrulama kurallarına göre nesneyi başlatmamız gerektiğinde olduğu gibi, yöntem olan ve nesneyi girdi olarak alan statik yöntemlerin örneklerini bulabiliriz . Örneğin, .NET , DateTime.TryParse(String s, DateTime d)nesneyi doğrulama ve somutlaştırma yöntemine sahiptir . Ancak parametre DateTime daçıkça olarak işaretlenir out.

Başka bir durum, nesneleri karşılaştırdığımızda ve istenen nesneyi, örneğin karşılaştırma sonucunun bir boole / tamsayı değeri yerine dönüş değeri olarak almak istediğimizde olabilir Team.GetHigherScorer(teamA, teamB).IncreaseRanking(). Bu daha temiz olacaktır:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(davanın basit olması için "çekilip çıkarılması").


1
Kişi "tüm nesneyi" geçirmez. Referansı, bellekteki çok az miktarda veri olan bir yere iletirsiniz. Performans üzerindeki etkisinden emin değilim, ama yine de ... "dışarı" işareti ne anlama geliyor?
Addison Crump

1
İfademden 'bütün' kelimesini bıraktım, kafa karıştırıcıydı. Asla performans veya boyut tasarlamadım, cevap tamamen programlama uygulamalarına dayanıyor. Her neyse, parametre değiştirici olarak kullanılan outbir .Netanahtar kelimedir. Parametrenin referans olarak iletildiğini belirtir. Ayrıntılar için bkz msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell

4
İlk cümle yanlıştır. eğer varsa class C { int x; static void M() { M mükemmel bir şekilde erişebilir x. Örneğin int y = (new C()).x;yasal.
Eric Lippert

@EricLippert :) Eminim ne demek istediğimi biliyorsun. Ustaların satırlar arasında nasıl okuyabileceği şaşırtıcı. Belki o cümleyi düzenlemem gerek. Açıklamak için böyle bir şey static void M() { this.x = 1; }mümkün değildir.
wonderbell

1
@wonderbell: Hayır, eminim ne demek istediğini bilmiyordum. Ne yazdığını biliyordum. Bunun this.xyanlış olduğunu çünkü xerişilemediğini değil, var olmadığını not ediyorum this. Bu bir erişim meselesi değil, bir varoluş meselesidir .
Eric Lippert

4

Bağımlılık Enjeksiyonu, statik yönteme çağrı yapmak için iyi bir neden olacaktır. Somut uygulamasının SomeClasskalıtım zincirine sahip olduğunu veya başka bir sınıfın uygulandığını varsayarsak . Bir nesnenin bir taklidini kullanabilir, metodunuzun olması gerekeni yaptığını garanti etmek için test amacıyla geçirebilir ve daha sonra bu durumu raporlayabilirsiniz.

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.