---
title: 'Günlükleme Cephesi ve Gerçekleştirim'
source: 'https://academia.sh/tr/kurslar/java-ekosistem/gunlukleme-cephesi-ve-gerceklestirim'
course: 'Derleme, Test ve Ekosistem'
language: tr
updated: '2026-08-23T14:25:06+00:00'
license: 'CC BY-SA 4.0'
---

# Günlükleme Cephesi ve Gerçekleştirim

Çağıranın sınıf dosyasının cepheyi andığı ama gerçekleştirimi anmadığı sabit havuzdan okunarak gösterilir; gerçekleştirim koşum sınıf yoluna bir servis bildirimiyle girer ve iki gerçekleştirim bulunduğunda seçimi yolun sırası belirler. Sınırlayıcı ölçüm, gerçekleştirim hiç bulunmadığında çağıranın yine de derlenip koştuğunu ama hiçbir kayıt üretmediğini gösterir.

Testin gördüğü yolu biz kurduk ve içine neyi koyacağımızı biliyorduk: hangi sahte tipin hangi
gerçek tipin yerine geçtiğini, hangi kurulumun test sınıf yoluna hangi bağımlılığı eklediğini,
adım adım biz yazdık. Bu derste yazan taraf değişiyor. Çağıran bir arayüze karşı derlenir, o
arayüzün arkasında duracak sınıfın adını **hiç yazmaz** — ne içe aktarır, ne örnekler, ne bir
dizgi olarak anar. Yine de program koştuğunda o adsız sınıf bulunur ve çağrılır. Soru şu: bir
ad, kaynakta hiç yazılmadan, koşum sınıf yoluna nasıl giriyor, ve orada birden fazla aday
varsa hangisinin kazanacağına ne karar veriyor?

Bu konu üç dersle günlüklemeyi ele alıyor, ama bu ilk ders günlük tutmanın kendisiyle değil,
günlükleme cephesinin kurduğu **bağımlılık yönüyle** ilgileniyor. Bir cephe — burada tek
yöntemli bir arayüz — çağıranın konuştuğu tek tip oluyor; arkasındaki gerçekleştirim çağırana
hiç görünmüyor. Aşağıdaki ölçüm bunu dört adımda kuruyor: önce derlemenin gerçekleştirimi hiç
görmeden geçtiğini ve sınıf dosyasının onu anmadığını, sonra gerçekleştirimin koşum sınıf
yoluna nasıl bir bildirimle girdiğini, sonra birden fazla gerçekleştirim olduğunda kazananı
neyin belirlediğini, son olarak da hiç gerçekleştirim yokken neyin olduğunu.

## Derleme Sınıf Yolunda Yalnız Cephe Var

**GL1.** Çağıran kaynak metninde yalnız cephe arayüzünün adını yazar; gerçekleştirim
sınıflarının adı kaynakta hiç geçmez, bu yüzden derleyicinin onları görmesine gerek yoktur.
**GL2.** Sınıf dosyasının sabit havuzu, yalnız kaynakta adı geçen tipleri taşır; kaynakta hiç
yazılmayan bir ad sabit havuzda da bulunmaz.

Ölçümün geri kalanında tekrar eden dört iş var: bir kaynağı diske yazmak, onu belirli bir
sınıf yoluna karşı derlemek, derlenmiş bir sınıfı belirli bir sınıf yoluyla koşturmak, ve bir
sınıf dosyasının sabit havuzunda hangi tiplerin adı geçtiğini okumak. Bu dördü aşağıdaki
yardımcı sınıfta toplanıyor; konunun kalan iki dersi de aynı dördü kullanıyor.

```java
// Arac.java — kaynak yazma, derleme, kosum ve sinif dosyasi okuma icin ortak yordamlar (yardimci sinif, main yok)
import java.io.*;
import java.lang.classfile.*;
import java.lang.classfile.constantpool.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;
import java.util.spi.ToolProvider;

class Arac {
    static Path yaz(Path dizin, String ad, String kaynak) throws IOException {
        Files.createDirectories(dizin);
        Path p = dizin.resolve(ad + ".java");
        Files.writeString(p, kaynak);
        return p;
    }

    static boolean derle(Path cikti, List<Path> sinifYolu, List<Path> kaynaklar) throws IOException {
        Files.createDirectories(cikti);
        List<String> arg = new ArrayList<>(List.of("-d", cikti.toString()));
        if (!sinifYolu.isEmpty()) {
            StringJoiner sj = new StringJoiner(File.pathSeparator);
            for (Path p : sinifYolu) sj.add(p.toString());
            arg.add("-classpath");
            arg.add(sj.toString());
        }
        for (Path k : kaynaklar) arg.add(k.toString());
        ToolProvider derleyici = ToolProvider.findFirst("javac").orElseThrow();
        StringWriter sessizCikti = new StringWriter();
        int sonuc = derleyici.run(new PrintWriter(sessizCikti), new PrintWriter(sessizCikti),
                arg.toArray(new String[0]));
        return sonuc == 0;
    }

    static void calistir(List<Path> sinifYolu, String anaSinif) throws Exception {
        URL[] url = new URL[sinifYolu.size()];
        for (int i = 0; i < url.length; i++) url[i] = sinifYolu.get(i).toUri().toURL();
        try (URLClassLoader yukleyici = new URLClassLoader(url, Arac.class.getClassLoader().getParent())) {
            Class<?> sinif = Class.forName(anaSinif, true, yukleyici);
            sinif.getMethod("main", String[].class).invoke(null, (Object) new String[0]);
        }
    }

    static Object alan(List<Path> sinifYolu, String anaSinif, String alanAdi) throws Exception {
        URL[] url = new URL[sinifYolu.size()];
        for (int i = 0; i < url.length; i++) url[i] = sinifYolu.get(i).toUri().toURL();
        try (URLClassLoader yukleyici = new URLClassLoader(url, Arac.class.getClassLoader().getParent())) {
            Class<?> sinif = Class.forName(anaSinif, true, yukleyici);
            sinif.getMethod("main", String[].class).invoke(null, (Object) new String[0]);
            return sinif.getField(alanAdi).get(null);
        }
    }

    static Set<String> atiflar(Path sinifDosyasi) throws IOException {
        Set<String> adlar = new TreeSet<>();
        ClassModel model = ClassFile.of().parse(sinifDosyasi);
        for (PoolEntry e : model.constantPool()) {
            if (e instanceof ClassEntry ce) adlar.add(ce.asInternalName().replace('/', '.'));
        }
        return adlar;
    }

    static void goster(String etiket, Object deger) {
        System.out.printf("%-62s: %s%n", etiket, deger);
    }

    static void bildir(Path dizin, String servis, String saglayici) throws IOException {
        Path d = dizin.resolve("META-INF").resolve("services");
        Files.createDirectories(d);
        Files.writeString(d.resolve(servis), saglayici + "\n");
    }

    static String cepheKaynagi() {
        return "public interface GunlukCephesi { void yaz(String ileti); int uretilenKayitSayisi(); }";
    }

    static String cagiranKaynagi() {
        return "import java.util.ServiceLoader;\n"
             + "public class Cagiran {\n"
             + "  static final class Sessiz implements GunlukCephesi {\n"
             + "    public void yaz(String ileti) { }\n"
             + "    public int uretilenKayitSayisi() { return 0; }\n"
             + "  }\n"
             + "  public static String secilenSinif = \"yok\";\n"
             + "  public static int uretilenKayit = -1;\n"
             + "  static GunlukCephesi bul() {\n"
             + "    for (GunlukCephesi g : ServiceLoader.load(GunlukCephesi.class, Cagiran.class.getClassLoader())) return g;\n"
             + "    return new Sessiz();\n"
             + "  }\n"
             + "  public static void main (String[] a) {\n"
             + "    GunlukCephesi g = bul();\n"
             + "    secilenSinif = g.getClass().getSimpleName();\n"
             + "    g.yaz(\"baslangic\"); g.yaz(\"ilerleme\"); g.yaz(\"bitis\");\n"
             + "    uretilenKayit = g.uretilenKayitSayisi();\n"
             + "  }\n"
             + "}";
    }

    static String gerceklestirimKaynagi(String ad) {
        return "public class " + ad + " implements GunlukCephesi {\n"
             + "  private int sayac = 0;\n"
             + "  public void yaz(String ileti) { sayac++; }\n"
             + "  public int uretilenKayitSayisi() { return sayac; }\n"
             + "}";
    }
}
```

`cagiranKaynagi()` çağıranın kaynağını üretiyor: `Cagiran` yalnız `GunlukCephesi` arayüzünü ve
`ServiceLoader`'ı içe aktarıyor, hiçbir gerçekleştirim sınıfının adını yazmıyor. Bulamazsa
kendi içinde tanımladığı `Sessiz` iç sınıfına düşüyor — bu da bir gerçekleştirim, ama
çağıranın **kendi kaynağında** duruyor, dışarıdan gelmiyor.

```java
// SadeceCephe.java — derleme sinif yolunda yalniz cephe varken cagiran derleniyor mu, sinif dosyasi kimi aniyor
import java.nio.file.*;
import java.util.*;

public class SadeceCephe {
    public static void main(String[] args) throws Exception {
        Path kok = Files.createTempDirectory("gl1");
        Path kaynak = kok.resolve("kaynak");

        Path sCephe = Arac.yaz(kaynak, "GunlukCephesi", Arac.cepheKaynagi());
        Path sCagiran = Arac.yaz(kaynak, "Cagiran", Arac.cagiranKaynagi());
        Path sA = Arac.yaz(kaynak, "GerceklestirimA", Arac.gerceklestirimKaynagi("GerceklestirimA"));
        Path sB = Arac.yaz(kaynak, "GerceklestirimB", Arac.gerceklestirimKaynagi("GerceklestirimB"));

        Path cepheD = kok.resolve("cephe");
        Path cagiranD = kok.resolve("cagiran");
        Path aD = kok.resolve("kayitA");
        Path bD = kok.resolve("kayitB");

        Arac.derle(cepheD, List.of(), List.of(sCephe));
        Arac.derle(aD, List.of(cepheD), List.of(sA));
        Arac.derle(bD, List.of(cepheD), List.of(sB));
        boolean cagiranDerlendi = Arac.derle(cagiranD, List.of(cepheD), List.of(sCagiran));

        Set<String> atif = Arac.atiflar(cagiranD.resolve("Cagiran.class"));

        Arac.goster("gerceklestirim adi derleme sinif yolunda hic olmadan cagiran derlendi mi", cagiranDerlendi);
        Arac.goster("cagiranin sinif dosyasi GunlukCephesi'ni aniyor mu", atif.contains("GunlukCephesi"));
        Arac.goster("cagiranin sinif dosyasi GerceklestirimA'yi aniyor mu", atif.contains("GerceklestirimA"));
        Arac.goster("cagiranin sinif dosyasi GerceklestirimB'yi aniyor mu", atif.contains("GerceklestirimB"));
    }
}
```

```
gerceklestirim adi derleme sinif yolunda hic olmadan cagiran derlendi mi: true
cagiranin sinif dosyasi GunlukCephesi'ni aniyor mu            : true
cagiranin sinif dosyasi GerceklestirimA'yi aniyor mu          : false
cagiranin sinif dosyasi GerceklestirimB'yi aniyor mu          : false
```

`GerceklestirimA` ve `GerceklestirimB` bu ölçümde gerçekten var: ikisi de derlenmiş, ikisinin
de sınıf dosyası diskte duruyor. `cagiranD`'nin derleme sınıf yolu bile onları içermiyor —
yalnız `cepheD` var — ve `Cagiran` yine de derleniyor (GL1). Sabit havuz okunduğunda
`GunlukCephesi` orada, `GerceklestirimA` ve `GerceklestirimB` orada değil (GL2). Bu, bir
tahmin değil; kaynakta hiç yazılmayan bir ad, derleyicinin üretebileceği hiçbir komutta da
geçmiyor, çünkü sınıf dosyası kaynağın **çevirisidir**, kaynağın bilmediği bir şeyi icat
etmez. Cephenin bütün gücü tam olarak burada: çağıran, arkada duracak sınıfın var olup
olmadığını bile derleme anında bilmek zorunda değil.

## Gerçekleştirimin Yola Bildirimle Girmesi

**GL3.** Gerçekleştirim koşum sınıf yoluna bir servis bildirimi dosyasıyla girer:
`META-INF/services/<cephe-arayüzünün-tam-adı>` adlı dosya, sağlayıcı sınıfın adını satır
olarak taşır. **GL4.** `ServiceLoader.load(...)` bu dosyayı okuyarak sağlayıcıyı bulur ve
örnekler; çağıran sağlayıcının kurucusunu hiçbir yerde çağırmaz.

```java
// ServisBildirimi.java — gerceklestirim yola bir servis bildirimiyle giriyor, cagiran onu ServiceLoader ile buluyor
import java.nio.file.*;
import java.util.*;

public class ServisBildirimi {
    public static void main(String[] args) throws Exception {
        Path kok = Files.createTempDirectory("gl2");
        Path kaynak = kok.resolve("kaynak");

        Path sCephe = Arac.yaz(kaynak, "GunlukCephesi", Arac.cepheKaynagi());
        Path sCagiran = Arac.yaz(kaynak, "Cagiran", Arac.cagiranKaynagi());
        Path sA = Arac.yaz(kaynak, "GerceklestirimA", Arac.gerceklestirimKaynagi("GerceklestirimA"));

        Path cepheD = kok.resolve("cephe");
        Path cagiranD = kok.resolve("cagiran");
        Path aD = kok.resolve("kayitA");

        Arac.derle(cepheD, List.of(), List.of(sCephe));
        Arac.derle(cagiranD, List.of(cepheD), List.of(sCagiran));
        Arac.derle(aD, List.of(cepheD), List.of(sA));
        Arac.bildir(aD, "GunlukCephesi", "GerceklestirimA");

        Object secilenOncesi = Arac.alan(List.of(cagiranD, cepheD), "Cagiran", "secilenSinif");
        Arac.goster("gerceklestirim kosum yolunda yokken dusulen sinif", secilenOncesi);

        List<Path> kosumYoluSonrasi = List.of(cagiranD, cepheD, aD);
        Object secilenSonrasi = Arac.alan(kosumYoluSonrasi, "Cagiran", "secilenSinif");
        Object kayitSonrasi = Arac.alan(kosumYoluSonrasi, "Cagiran", "uretilenKayit");
        Arac.goster("gerceklestirim yola bildirimle girince secilen sinif", secilenSonrasi);
        Arac.goster("uretilen kayit sayisi", kayitSonrasi);
    }
}
```

```
gerceklestirim kosum yolunda yokken dusulen sinif             : Sessiz
gerceklestirim yola bildirimle girince secilen sinif          : GerceklestirimA
uretilen kayit sayisi                                         : 3
```

`aD` dizini iki şey taşıyor: `GerceklestirimA.class` ve `META-INF/services/GunlukCephesi`
adlı, içinde tek satır `GerceklestirimA` yazan bir bildirim dosyası. Koşum sınıf yoluna `aD`
eklendiğinde `Cagiran` içindeki `ServiceLoader.load` çağrısı bu dosyayı okuyor,
`GerceklestirimA`'yı yüklüyor ve örnekliyor — kod tarafında hiçbir satır `new
GerceklestirimA()` yazmadan (GL3, GL4). Üç `yaz` çağrısının üçü de bu örneğe ulaşıyor ve
sayaç üçe çıkıyor. `aD` koşum sınıf yolundan çıkarılınca aynı `Cagiran.class`, hiç yeniden
derlenmeden, kendi `Sessiz` düşüşüne geri dönüyor. Değişen tek şey koşum sınıf yolunun
içeriği; `Cagiran.class` dosyası ikisinde de birebir aynı bayt dizisi.

## İki Gerçekleştirim Olunca Sırayı Yol Belirliyor

**GL5.** Koşum sınıf yolunda aynı servis için birden fazla sağlayıcı bildirildiğinde
`ServiceLoader`'ın döndürdüğü ilk sağlayıcı, sınıf yolu girişlerinin **sırasına** bağlıdır.
**GL6.** Sıra değişince seçilen gerçekleştirim değişir, ama ne derleme ne koşum hatası
oluşur — ikisi de "tamam" sonucuyla biter.

```java
// SiraKazanani.java — kosum sinif yolunda iki gerceklestirim varken kazanani yolun sirasi belirliyor
import java.nio.file.*;
import java.util.*;

public class SiraKazanani {
    public static void main(String[] args) throws Exception {
        Path kok = Files.createTempDirectory("gl3");
        Path kaynak = kok.resolve("kaynak");

        Path sCephe = Arac.yaz(kaynak, "GunlukCephesi", Arac.cepheKaynagi());
        Path sCagiran = Arac.yaz(kaynak, "Cagiran", Arac.cagiranKaynagi());
        Path sA = Arac.yaz(kaynak, "GerceklestirimA", Arac.gerceklestirimKaynagi("GerceklestirimA"));
        Path sB = Arac.yaz(kaynak, "GerceklestirimB", Arac.gerceklestirimKaynagi("GerceklestirimB"));

        Path cepheD = kok.resolve("cephe");
        Path cagiranD = kok.resolve("cagiran");
        Path aD = kok.resolve("kayitA");
        Path bD = kok.resolve("kayitB");

        Arac.derle(cepheD, List.of(), List.of(sCephe));
        Arac.derle(cagiranD, List.of(cepheD), List.of(sCagiran));
        Arac.derle(aD, List.of(cepheD), List.of(sA));
        Arac.derle(bD, List.of(cepheD), List.of(sB));
        Arac.bildir(aD, "GunlukCephesi", "GerceklestirimA");
        Arac.bildir(bD, "GunlukCephesi", "GerceklestirimB");

        Object aOnce = Arac.alan(List.of(cagiranD, cepheD, aD, bD), "Cagiran", "secilenSinif");
        Object bOnce = Arac.alan(List.of(cagiranD, cepheD, bD, aD), "Cagiran", "secilenSinif");

        Arac.goster("A once verilen kosum sinif yolunda secilen", aOnce);
        Arac.goster("B once verilen kosum sinif yolunda secilen", bOnce);
        Arac.goster("ikisi de hatasiz kosup yalniz sirayla farklilasti mi", !aOnce.equals(bOnce));
    }
}
```

```
A once verilen kosum sinif yolunda secilen                    : GerceklestirimA
B once verilen kosum sinif yolunda secilen                    : GerceklestirimB
ikisi de hatasiz kosup yalniz sirayla farklilasti mi          : true
```

`aD` ve `bD` birbirinden habersiz iki dizin; her biri kendi sınıfını ve kendi servis
bildirimini taşıyor. Koşum sınıf yolu `[cagiranD, cepheD, aD, bD]` sırasıyla kurulduğunda
`ServiceLoader` önce `aD`'nin bildirimine rastlıyor ve `GerceklestirimA`'yı döndürüyor; aynı
iki dizin `bD, aD` sırasıyla verildiğinde kazanan `GerceklestirimB` oluyor (GL5). `Cagiran`
kaynağı, `GunlukCephesi` arayüzü, iki gerçekleştirimin kendisi — hiçbiri iki koşum arasında
değişmedi; değişen yalnız listenin sırası. Kod tarafında hiçbir yerde bir çakışma uyarısı ya
da hata yok (GL6): iki sağlayıcı bulunması, K05'in ortak tanımındaki "koşum sınıf yolunda iki
gerçekleştirim bulunduğunda seçim yolun sırasına göre değişir, hata yok" gözlemiyle aynı
kalıba giriyor, burada arayüz düzeyinde bir kez daha görülüyor.

## Gerçekleştirim Hiç Bulunmazsa

**GL7.** Koşum sınıf yolunda hiçbir sağlayıcı bulunmazsa `ServiceLoader.load(...)` boş bir
yineleyici döner; çağıran bunu bir istisna olarak değil, kendi tanımladığı bir varsayılanla
karşılar. **GL8.** Bu durumda program hatasız çalışır ama hiçbir gerçekleştirim
`uretilenKayitSayisi()`'nı artırmadığı için üretilen kayıt sıfırdır.

```java
// GerceklestirimYok.java — gerceklestirim kosum yolunda hic yokken cagiran hatasiz kosuyor ama hicbir kayit uretmiyor
import java.nio.file.*;
import java.util.*;

public class GerceklestirimYok {
    public static void main(String[] args) throws Exception {
        Path kok = Files.createTempDirectory("gl4");
        Path kaynak = kok.resolve("kaynak");

        Path sCephe = Arac.yaz(kaynak, "GunlukCephesi", Arac.cepheKaynagi());
        Path sCagiran = Arac.yaz(kaynak, "Cagiran", Arac.cagiranKaynagi());

        Path cepheD = kok.resolve("cephe");
        Path cagiranD = kok.resolve("cagiran");
        Arac.derle(cepheD, List.of(), List.of(sCephe));
        Arac.derle(cagiranD, List.of(cepheD), List.of(sCagiran));

        List<Path> kosumYolu = List.of(cagiranD, cepheD);
        boolean hataAlmadanKostu;
        try {
            Arac.calistir(kosumYolu, "Cagiran");
            hataAlmadanKostu = true;
        } catch (Exception e) {
            hataAlmadanKostu = false;
        }
        Object secilen = Arac.alan(kosumYolu, "Cagiran", "secilenSinif");
        Object kayit = Arac.alan(kosumYolu, "Cagiran", "uretilenKayit");

        Arac.goster("gerceklestirim kosum yolunda hic yokken hata almadan kosuyor mu", hataAlmadanKostu);
        Arac.goster("dusulen sinif", secilen);
        Arac.goster("uretilen kayit sayisi", kayit);
    }
}
```

```
gerceklestirim kosum yolunda hic yokken hata almadan kosuyor mu: true
dusulen sinif                                                 : Sessiz
uretilen kayit sayisi                                         : 0
```

Bu ölçümün koşum sınıf yolunda `GerceklestirimA` da `GerceklestirimB` da yok — yalnız cephe
ve çağıran var. Program yine de tamamlanıyor, hiçbir istisna fırlatmıyor (GL7), ve
`uretilenKayit` sıfırda kalıyor (GL8). Bu, dersin sınırlayıcı ölçümü: cephe, çağıranla
gerçekleştirim arasındaki bağımlılığı **yok etmiyor**, yönünü çeviriyor. Gerçekleştirim
hiç yoksa çağıran bunu bir hata olarak değil bir **boşluk** olarak görüyor ve kendi
`Sessiz` düşüşüyle dolduruyor. Üretilen kayıt sayısının sıfır olması burada bir kusurun
işareti değil; çağıranın kendi kaynağında yazdığı bir kuralın sonucu. Bir günlükleme
cephesinin gerçek dünyadaki gerçekleştirimleri de bu sözü taşır: gerçekleştirim
bağlanmamışsa program çökmez, yalnız konuşmaz. Bu, cephe düzeneğinin çağırana verdiği asıl
güvencedir — çağıranın kendisi hangi gerçekleştirimin koşum sınıf yoluna gireceğini
bilmeden yazılabilir, çünkü en kötü ihtimalle davranış "hiç kayıt yok" olur, "program
çalışmıyor" değil. Bu güvence bir bedel de taşır: koşum sınıf yolu yanlış kurulduğunda
ortada hiçbir hata mesajı olmadığı için eksik kalan kayıtların fark edilmesi, derleyicinin
reddettiği bir satırı fark etmekten çok daha zordur.

## Özet

- Çağıran kaynak metninde yalnız cephe arayüzünün adını yazar; derleme sınıf yolunda
  gerçekleştirim hiç bulunmasa da çağıran derlenir.
- Sınıf dosyasının sabit havuzu kaynakta yazılan tipleri taşır: `GunlukCephesi` orada,
  kaynakta hiç geçmeyen `GerceklestirimA` ve `GerceklestirimB` orada değil.
- Gerçekleştirim koşum sınıf yoluna bir servis bildirim dosyasıyla girer; `ServiceLoader` bu
  bildirimi okuyarak sağlayıcıyı çağıranın hiçbir satırında adı geçmeden bulur ve örnekler.
- Koşum sınıf yolunda birden fazla sağlayıcı bildirildiğinde kazananı sınıf yolu
  girişlerinin sırası belirler; sıra değişince seçim değişir ama hata oluşmaz.
- Sınırlayıcı ölçüm: gerçekleştirim hiç bulunmadığında çağıran yine derlenip hatasız koşar,
  ama hiçbir kayıt üretmez — cephe bağımlılığı yok etmiyor, yönünü çeviriyor.

## Sonraki Adım

Bu derste ölçülen şey bir adın yola nasıl girdiğiydi: bildirimle, sırayla, ya da hiç
girmeden. Sıradaki ders aynı çağrı kümesini sabit tutup değişen tek şeyi bir eşik yapıyor —
aynı üç çağrı iki ayrı eşikle koşturulduğunda kaç tanesi gerçekten bir kayda dönüşüyor, ve
eşiğin altında kalan bir çağrının hâlâ bir bedeli var mı?
