İçeriğe geç

Soyutlama ve Dört Sütun — Hangi Değişikliğe Hangisi Yardım Eder?

Orta 9 dk Çok sık karşılaşılır

Önce şunu oku: Polimorfizm ve Dinamik Bağlama — Kararı Kim Veriyor? , Interface ve Abstract Class — Rol mü, İskelet mi?

30 saniyede özet

Kapsülleme, soyutlama, kalıtım ve polimorfizm dört ayrı ezber değil, dört ayrı değişikliğe karşı sigorta. Bu ders eksik kalan soyutlamayı tanıtıyor ve dördünü tek bir banka kodunda yan yana koyuyor.

Televizyonu açarken kumandanın içindeki devreyi düşünmezsin. Düğmeye basarsın, iş olur. Kumanda değişse bile düğmeler aynı kaldıkça hayatın değişmez.

Dört sütun, bir çatı.
Adım adım oku
  1. Kapsülleme: kasaya yalnızca veznedar dokunur; kural tek kapıda.
  2. Soyutlama: düğmeleri görürsün, kabloları görmezsin.
  3. Kalıtım ortak kodu paylaştırır, polimorfizm aynı düğmeyi her cihazda çalıştırır.
  4. Dördü birlikte, değişikliği küçük ve yerel tutar.
  1. Bayt: Dört sütunun adlarını ezberledim. Ama hangisi ne işe yarıyor, karışıyor.

  2. Sen: Bence de. Hepsi biraz aynı gibi.

  3. Bayt: Ezberi bırakalım. Her birine bir değişiklik isteği getirelim ve kim korunuyor, bakalım.

Soyutlama: ne yapıldığı, nasıl değil

abstractionBir şeyi kullanana yalnızca ne yaptığını gösterip nasıl yaptığını saklamak. Java'da çoğu zaman bir arayüz ya da abstract sınıf ile kurulur.Sözlükte gör →, bir şeyi kullanan kişiye yalnızca ne yaptığını gösterip nasıl yaptığını saklamaktır. Java’da bunun en sık hâli bir arayüzdür: BankGateway “para gönder” der, hangi bankaya nasıl bağlandığını söylemez.

TransferService bir BankGateway istediğinde, arkadaki gerçek istemciyi değiştirmek servisi değiştirmez. Testte sahte bir gateway verirsin, canlıda gerçeğini.

Kafam karıştı, daha basit anlat

Soyutlama bir kumandadır. Düğmeler aynı kaldıkça içindeki devreyi kimse dert etmez.

Hızlı kontrolBaşlangıç

Soyutlama en kısa hâliyle nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

TransferService constructor'ında bir BankGateway arayüzü alıyor. Bunun en somut kazancı hangisi?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Dört sütun, dört değişiklik

kapsüllemeBir nesnenin iç durumunu yalnızca kendi metotlarından değiştirilebilir kılmak. Amaç alanları gizlemek değil, nesnenin kuralını (invariant) korumaktır.Sözlükte gör → bir kuralı tek kapıda toplar: bakiyeyi yalnızca withdraw() değiştirebiliyorsa, limit kuralı da yalnızca orada yaşar.

polimorfizmAynı çağrının, nesnenin gerçek tipine göre farklı davranış üretmesi. Java'da override edilmiş örnek metotlarıyla sağlanır.Sözlükte gör → yeni bir türü tek yere toplar: herkes method.pay() derse, QR ödeme eklemek yeni bir sınıf yazmak demektir. kalıtımBir sınıfın başka bir sınıfı extends ile genişletip onun API'sini ve uygulamasını devralması. "B, bir A'dır" ilişkisini ifade eder.Sözlükte gör → ise ortak kodu paylaştırır; değişikliği de paylaştırdığını unutmamak gerekir.

Kod, ödeme türüne göre üç farklı sınıfta switch (kind) yapıyor. QR ödeme eklemek istiyorsun. Kaç var olan dosyayı değiştirmen gerekir? Cevabı göster

Üç. Her switch’e yeni bir dal eklemelisin. Birini unutursan derleyici çoğu zaman uyarmaz ve hata, o kod ilk çalıştığında ortaya çıkar.

Polimorfizm bu üç switch’i siler, ama bir şartla: ortada ortak bir tip olmalı. Ortak tip olmadan çağrılacak ortak bir metot da yoktur.

Kafam karıştı, daha basit anlat

Kapsülleme kuralı, polimorfizm yeni türü, soyutlama bağımlılığı tek yerde tutar. Kalıtım kodu paylaştırır ama değişikliği de paylaştırır.

Hızlı kontrolOrta

Bakiye alanı public ve dört farklı sınıf onu doğrudan değiştiriyor. 'Bakiye -limit altına inmesin' kuralı geldi. Asıl sorun hangi sütunun eksikliği?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Polimorfizmin switch (kind) dallarını silebilmesi için ne gerekir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

Değişiklik isteği geldi

Tohum 709444

Oynat ya da adımla.

Hız
Adım 0

Şu an ne oldu?

QR ödeme ekle

Bu istek en çok soyutlama + polimorfizm ile ilgili. Hangi anahtarlar açık, ona bak.

Görevler0/3

  • QR ödemeyi ekle ve bir switch'i unutaçık

    İpucu

    Varsayılan ayarlar yeter.

  • QR ödemeyi var olan hiçbir dosyaya dokunmadan ekleaçık

    İpucu

    Tek anahtar yetmez.

  • Kart ücretini havaleye dokunmadan değiştiraçık

    İpucu

    Ortak kodu nerede tutuyorsun?

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. QR ödeme için iki switch değişti, üçüncüsü unutuldu.
  2. Yalnızca polimorfizmi aç. Ortak tip olmadığı için yine switch.
  3. Soyutlamayı da aç. Tek yeni dosya, sıfır değişiklik.
  4. İsteği kart ücreti yap. Taban sınıftaki değişiklik havaleyi de etkiledi; kalıtımı kapatınca etkilemedi.
  5. Bakiye limitini ve testi dene. Kapsüllemeyi ve soyutlamayı kapatıp aç, farka bak.
Hızlı kontrolOrta

Kart ücreti hesabı abstract BasePayment.fee() içinde ve havale de onu miras alıyor. Yalnızca kart ücreti değişecek. Risk nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Tuzaklar

Tek uygulamalı arayüz. Değişmesi beklenmeyen her sınıfa bir arayüz eklemek, kodu okumayı zorlaştırır. Arayüzü, arkası gerçekten değişecek ya da testte taklit edilecekse yaz.

Yalnızca getter ve setter. Her alana bir setter vermek kapsülleme değildir. Kural yine dışarıda kalır; kapsülleme anlamlı metotlarla gelir.

Kod paylaşmak için kalıtım. İki sınıf birkaç satır ortak diye taban sınıf açmak, ileride ayrışacak davranışı birbirine bağlar. Önce kompozisyonu düşün.

Kafam karıştı, daha basit anlat

Sütunları ihtiyaç kadar dik. Arkası değişmeyecek bir sınıfa arayüz, kuralı olmayan bir alana metot gerekmez.

Hızlı kontrolOrta

Her alana bir getter ve bir setter yazılmış. Bu sınıf kapsüllenmiş sayılır mı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Yalnızca bir uygulaması olan ve değişmesi beklenmeyen bir yardımcı sınıfa arayüz eklemek ne zaman gereksizdir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aşağıdaki örnek, simülatördeki banka kodunun dört sütunla yazılmış hâli.

Derinleş · Ödemeler: dört sütun tek kodda 5 dosya · ~96 satır · ilk okumada atlayabilirsin
Proje dosyaları

src/main/java/com/bank/account/ Account.java Kapsülleme: bakiyeyi yalnızca anlamlı metotlar değiştirir; limit kuralı tek yerde.

src/main/java/com/bank/account/Account.java
public final class Account {
private final String iban;
private final BigDecimal overdraftLimit;
private BigDecimal balance; // nobody outside can set it
public Account(String iban, BigDecimal overdraftLimit) {
this.iban = iban;
this.overdraftLimit = overdraftLimit;
this.balance = BigDecimal.ZERO;
}
public void deposit(BigDecimal amount) {
requirePositive(amount);
balance = balance.add(amount);
}
// The only way down: the overdraft rule lives here and nowhere else.
public void withdraw(BigDecimal amount) {
requirePositive(amount);
BigDecimal next = balance.subtract(amount);
if (next.compareTo(overdraftLimit.negate()) < 0) {
throw new InsufficientFundsException(iban, amount);
}
balance = next;
}
public BigDecimal balance() {
return balance;
}
private static void requirePositive(BigDecimal amount) {
if (amount.signum() <= 0) throw new IllegalArgumentException("Tutar pozitif olmalı");
}
}

src/main/java/com/bank/payment/ PaymentMethod.java Soyutlama: ödeme yöntemi bir arayüz; servis yalnızca ne yapıldığını bilir.

src/main/java/com/bank/payment/PaymentMethod.java
// Abstraction: what a payment method does, not how.
public interface PaymentMethod {
PaymentResult pay(Account from, BigDecimal amount);
BigDecimal fee(BigDecimal amount);
}

src/main/java/com/bank/payment/ QrPayment.java Polimorfizm: QR ödeme yeni bir sınıf; var olan koda dokunulmuyor.

src/main/java/com/bank/payment/QrPayment.java
// Polymorphism: a new kind is a new class. PaymentService, the fee report and
// the monthly statement call method.pay() / method.fee() and never change.
public final class QrPayment implements PaymentMethod {
private final FeePolicy feePolicy;
private final QrNetwork network;
public QrPayment(FeePolicy feePolicy, QrNetwork network) {
this.feePolicy = feePolicy;
this.network = network;
}
@Override
public PaymentResult pay(Account from, BigDecimal amount) {
from.withdraw(amount.add(fee(amount)));
return network.settle(amount);
}
@Override
public BigDecimal fee(BigDecimal amount) {
return feePolicy.feeFor(amount);
}
}

src/main/java/com/bank/payment/ FeePolicy.java Kalıtım yerine kompozisyon: ücret politikası bir nesne, her tür kendi politikasını taşır.

src/main/java/com/bank/payment/FeePolicy.java
// Composition over a shared base class: changing the card fee cannot touch
// transfers, because each payment kind holds its own policy object.
public interface FeePolicy {
BigDecimal feeFor(BigDecimal amount);
static FeePolicy flat(BigDecimal fee) {
return amount -> fee;
}
static FeePolicy percent(BigDecimal rate, BigDecimal minimum) {
return amount -> amount.multiply(rate).setScale(2, RoundingMode.HALF_EVEN).max(minimum);
}
}

src/test/java/com/bank/transfer/ TransferServiceTest.java Soyutlama ve test: servis gateway'i dışarıdan alıyor; testte sahte bir tane veriliyor.

src/test/java/com/bank/transfer/TransferServiceTest.java
class TransferServiceTest {
// The service asks for a BankGateway, so the test can hand it a fake.
private final RecordingGateway gateway = new RecordingGateway();
private final TransferService service = new TransferService(gateway);
@Test
void sendsTheTransferThroughTheGateway() {
Account from = new Account("TR01", BigDecimal.ZERO);
from.deposit(new BigDecimal("100.00"));
service.transfer(from, "TR02", new BigDecimal("40.00"));
assertThat(gateway.sent()).containsExactly(new SentTransfer("TR01", "TR02", new BigDecimal("40.00")));
assertThat(from.balance()).isEqualByComparingTo("60.00");
}
}

Kendini sına

Şimşek turu1/4

Soyutlama, bir şeyin nasıl yapıldığını saklayıp ne yaptığını gösterir.

Soru 1/3İleri

Ödeme türüne göre üç sınıfta switch var. Yeni bir tür eklenip bir switch unutuldu. Hata ne zaman ortaya çıkar?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aklında kalacak üç şey

  1. 1 Soyutlama, kullanana yalnızca ne yapıldığını gösterir, nasıl yapıldığını saklar. Kod bir arayüze konuşunca arkasındaki sınıf değişebilir.
  2. 2 Her sütun bir tür değişikliği tek yere toplar: kapsülleme kuralı, soyutlama bağımlılığı, polimorfizm yeni türü, kalıtım ortak kodu.
  3. 3 Polimorfizm ortak bir tip ister. Ortak tip yoksa kod yine türe göre dallanır ve her yeni tür bütün switch'leri gezer.
0/4 kart bu dersten toplandı