Bugüne kadar birçok yerde okudum/denk geldim.

static methodları kullanmayın/tercih etmeyin diyorlar.

tamam kullanmayalım ama ne zaman kullanmayalım?

tamam kullanmayalım ama ne nerde kullanmayalım ?

Burada ki kullanmama / tercih etmememizin sebebi nedir ? dezavantajı nedir ?

Math sınıfı yazmış adamlar methodlar static onu damı kullanmayalım.

Yanlış mı düşünüyorum :)

soruldu: 28 Ara '13, 20:16

ismailkocacan's gravatar image

ismailkocacan
2.4k31733
cevap kabul oranı: 13%

değiştirildi: 09 Haz '14, 15:33

%C3%B6zcanacar's gravatar image

özcanacar ♦♦
17.2k59183183


Ben kendimden örnek vereyim. Burada vereceğim örnekler daha çok işlevsel yönü ile ilgili. yoksa statik metod kullanmanın memory leaklere yol açabileceği senaryolar da mevcut.

  • Statik kullanılmasının mantıksız olduğu bir örnek vereyim mesela:

Üzerinde çalıştığım bir uygulamada bir rest client class'ı oluşturmam gerekiyor. Bu webservis clientinde property olarak bir rest servis url adresi propertysi var, bu property'den class'ın içerisindeki bütün metodlar faydalanıyor. Ayrıca birden fazla adres için aynı metodda bu çağrıları oluşturup onlardan çağrı yapmam gerekiyor.

RestClient client = new RestClient("www.adres.com");
RestClient client2 = new RestClient("www.adres2.com");

sonrasında bu metodlar üzerinden çeşitli çağrılar yapıyorum... static metodda "this" çağrısını yapıp property'i geritemeyeceğinizden eğer bütün metodlar statik olsa her metod çağrısına web adresini eklemek zorunda kalabiliriz.

  • Statik metod kullanmanın işimize yarayacağı bir duruma örnek vermek gerekirse:

Benim neredeyse her geliştirdiğim uygulamada kullandığım "utility" classım vardır. Bu classtaki bütün çağrılar statik. Bu sayede nerede olursam olayım:

Utility.getYMDString(Calendar.getInstance.getTime());

(bir date değerinin yyyy-mm-dd şeklinde string değerini getirir)

şeklinde, herhangi bir instance yaratmaya gerek kalmadan tek kullanımlık fnoksiyonlar oulşturabiliyorum.

Bunlar tamamen işlevsel örnekler, bunların haricinde mesela bir singleton object yaratmak istersek statik metodlardan faydalanmak zorundayız: (kod alıntıdır).

public class ClassicSingleton {
   private static ClassicSingleton instance = null;
   protected ClassicSingleton() {
      // Exists only to defeat instantiation.
   }
   public static ClassicSingleton getInstance() {
      if(instance == null) {
         instance = new ClassicSingleton();
      }
      return instance;
   }
}

Çünki burada oluşturulan nesnenin tek olması gerekmektedir. Buradaki metodu static yapmamış olsak class2ı kullanabilmek için her seferinde :

ClassicSingleton singleton = new ClassicSingleton();

şeklinde bir instance oluşturmamız gerekecekti, haliyle her seferinde memoryde yeni bir kopyası oluşacağından fonksiyon da singleton olamayacaktı.

Yine başka bir örnek, web frameworklerde "stateless" durumunun yaratılması için yine static metodlara ihtiyaç duyuluyor..

Açıkçası benim dilim bu kadar dönüyor, benden daha bilgili arkadaşlar daha iyi anlatacaktır :)

permanent link

cevaplandı: 30 Ara '13, 13:46

dreampowder's gravatar image

dreampowder
3.3k112849
cevap kabul oranı: 23%

açıklama güzel ve yeterli hocam. Soruyu sormaktaki amacım farkındalık oluşturmaktı :)

(30 Ara '13, 15:15) ismailkocacan ismailkocacan's gravatar image

gturedi'nin cevabı en doğru cevap. cevabı küçük bir örnekle desteklemek gerekirse, elimizde EftYap isimli bir methodumuzun olduğunu ve buna birim testi yazmak istediğimizi düşünelim (C# 'ta yazılmıştır)

public void EftYap(string kaynakHesap, string hedefHesap, decimal miktar)
{
    if (DateTime.Now.Hour > 15)
        throw new EftException("Saat 15'ten sonra EFT yapamazsınız.");

    EftIslemleri.EftyiGerceklestir(kaynakHesap, hedefHesap, miktar);
}

Bu methodda iki adet static method kullanımı mevcut. Birincisi ve daha göze çarpanı, EftIslemleri isimli sınıf üzerinden eft işlemi yapan method. İkincisi ise mevcut saati almak için kullandığımız DateTime.Now methodu.

Kolay olan örneği ben veriyorum, zor olanı da isteyenlere bırakıyorum :)

Eğer yazdığımız birim testini gündüz çalıştırırsak problem yaşamayacağız, gece çalıştırırsak methodumuz exception fırlatacak ve birim testimiz çalışmayacaktır. Peki gece çalıştırdığımızda da birim testlerin çalışması için ne yapmamız gerekir?

Cevap: static methodları interface methodları ile değiştireceğiz.

Aşağıdaki interface ve sınıfları oluşturalım

public interface IDateTime {
    DateTime Now();
}

public class RealDateTime : IDateTime {
    public DateTime Now()
    {
        return DateTime.Now;
    }
}

public class FakeDateTime : IDateTime {

    private string _fakeFormat;

    public FakeDateTime(string fakeFormat)
    {
        this.fakeFormat = fakeFormat;
    }

    public DateTime Now()
    {
        return DateTime.Parse(fakeFormat);
    }
}

gerçek methodumuzu ise aşağıdaki şekilde değiştireceğiz

public void EftYap(string kaynakHesap, string hedefHesap, decimal miktar, IDateTime dateTime)
{
    if (dateTime.Now().Hour > 15)
        throw new EftException("Saat 15'ten sonra EFT yapamazsınız.");

    EftIslemleri.EftyiGerceklestir(kaynakHesap, hedefHesap, miktar);
}

Böylelikle birim testimizi çağırdığımız yerde, gece de olsa testi kandırabilecek ve gündüz saatiymiş gibi eft'yi test edebileceğiz. Testimizin iki methodu olsun

Saat17denOnceEftYapildiginiTestEt
Saat17denSonraEftYapilamadiginiTestEt

ilk testi çağırırken

EftYap("kaynak", "hedef", 100, new FakeDateTime("2014-05-09 12:03:01"));

ikinci testi çağırırken

EftYap("kaynak", "hedef", 100, new FakeDateTime("2014-05-09 23:45:13"));

şeklinde kullanacağız.

Methodumuzu gerçek ortamda kullanan yerlerde ise

EftYap("kaynak", "hedef", 100, new RealDateTime());

şeklinde yazmamız gerekmektedir.

Diğer static methodu da buna benzer şekilde değiştirebilirsiniz.

permanent link

cevaplandı: 09 May '14, 10:54

tilikoglu's gravatar image

tilikoglu
8602816
cevap kabul oranı: 18%

değiştirildi: 09 May '14, 10:55

cevap güzeldi hocam.

(09 May '14, 16:20) ismailkocacan ismailkocacan's gravatar image

teşekkür ederim

(15 May '14, 22:31) tilikoglu tilikoglu's gravatar image

statik metotlar override edilemedigi icin birim test yazarken mock'lama esnasında zorluk cıkarıyor: http://googletesting.blogspot.com.tr/2008/12/static-methods-are-death-to-testability.html

permanent link

cevaplandı: 24 Nis '14, 02:49

gturedi's gravatar image

gturedi
2.8k41538
cevap kabul oranı: 26%

Statik metotlar aksine kullanım kolaylığı sağlar ve doğru yerde kullanıldığında performans kazandırır.

permanent link

cevaplandı: 30 Ara '13, 08:02

Gnosis00's gravatar image

Gnosis00
1766914
cevap kabul oranı: 0%

Katılıyorum... Bende bugüne kadar üzerinde çalıştığım projelerde static methodları gerektiği yerde kullanmaya çalıştım.

Ama denk geldiğim bazı yazılarda ise "static methodları kullanmayın" diye müphem cümleler görünce böyle bir sorunun varlığının ve cevabının nedenleri ile birlikte olmasını istedim.

(30 Ara '13, 15:12) ismailkocacan ismailkocacan's gravatar image

Bu buyuk bir tartisma konusu. Dileyenle saatlerce tartisabilirim.

Özellikle Java 1.5ten sonra hele de 1.7deki Garbage Collector iyilestirmelerinden sonra hala statik metod kullanimina insanlari iten bir sey varsa lutfen paylassin ki birseyler ogrenelim.

Bir de her yerde "Yerinde kullandiktan sonra daha performansli" yorumunu duyuyorum ama daha yerinin neresi oldugunu duydugum olmadi. Gnosis00 sözüm meclisten disari, gercekten satasma amaciyla soylemiyorum, sen de herkesle ayni cumleyi kullandin tek gunahin bu :) Varsa yorumun sohbet edebiliriz.

permanent link

cevaplandı: 31 Ara '13, 09:58

MCY's gravatar image

MCY
1.1k2622
cevap kabul oranı: 16%

@MCY amacım zaten bir tartışma ortamı ve fikir çoşkusu oluşturmak :)

Bence "Soru sormak" kavramı sadece insanların bilmediği birşeyi öğrenmek namına olmamalı.

Bildiği birşeyi de sorabilmeli.

Tamam biliyoruz,öğrendik ama belki yanlış öğrendik ve hala yanlış biliyor olabiliriz :)

@Gnosis00 "kullanım kolaylığı sağlar" sağlar derken instance oluşturmadan kullanılabileceğine dikkat çekmek istedi sanırım.

Yine @dreampowder da Utility sınıfındaki getYMDString methodunu static olarak yazmış.

Benimde aynı şekilde, ToastHelper isminde bir sınıfım ve aşağıdaki methodlarım var.

public static void showSuccessToast(Activity activity,String message)

public static void showSuccessToast(Context context,String message)

public static void showFailToast(Activity activity,String message)

public static void showFailToast(Context context,String message)

Ve aşağıdaki gibi pratik bir şekilde çağırabiliyorum.

ToastHelper.showSuccessToast(this,"hayırlı işler bol güneşler");

Randevu isminde bir sınıfım var. Sınıfdan nesne oluşturan aşağıdaki gibi static bir methodum var.

public static Randevu create()
{
    return new Randevu();
}

Her defasında new Randevu(); yazmak yerine aşağıdaki gibi bir yöntemle oluşturmayı tercih ediyorum.

Randevu randevu=Randevu.create();

Ben methodları pratik çağıracağım,ne kadar sınıf varsa hepsinin methodunu static olarak yazayım da olmaz tabiki :)

(31 Ara '13, 13:56) ismailkocacan ismailkocacan's gravatar image
2

@mcy bazen hersey OOP ve Design Patterns'e uygun cozulemiyor, örnegin Web Framework'ler bircok yerde static metodlar kullanmak zorunda kaliyor, Play Framework ile yazilmis projelere bakarsan bu tür kullanimlarla karsilasablirsin.

(25 Nis '14, 05:47) CemIkta ♦ CemIkta's gravatar image
Cevabınız
toggle preview

Bu soruyu takip et

E-Posta üzerinden:

Üyelik girişi yaptıktan sonra abonelik işlemlerini yapabilirsiniz

RSS üzerinden:

Cevaplar

Cevaplar ve Yorumlar

Yazı Formatlama

  • *italic* ya da _italic_
  • **bold** ya da __bold__
  • link:[text](http://url.com/ "başlık")
  • resim?![alt text](/path/img.jpg "başlık")
  • liste: 1. Foo 2. Bar
  • temel HTML etiketleri de kullanılabilir

Bu sorunun etiketleri:

×1

Soruldu: 28 Ara '13, 20:16

Görüntüleme: 1,541 kez

Son güncelleme: 09 Haz '14, 15:33

Benzer sorular

powered by BitNami OSQA