@shadow_0771, OOP öğrenimi kapsamında koduna geri bildirim istedi.

Peki... #kodu_kızartıyoruz!

Konsolda RPG — temel bir şey. Kod görevini yerine getiriyor, ancak ölçeklendirmeye kalktığınızda BÜÜÜÜÜÜÜÜÜK sorun çıkaracak şekilde yazılmış. En önemli sorunları inceleyelim 👇

1️⃣ Ctrl+C, Ctrl+V kalıtımı
Zırh hiyerarşisine bakalım:
class Armor(Item):
def __init__(self, name, category, strength=None, value_strength=None...): # ve 100500 argüman daha
super().__init__(name, category)
# ...

class Helmet(Armor):
def __init__(self, ...):
super().__init__(...)

class Chestplate(Armor):
# Helmet'in kopyası

class Greaves(Armor):
# Chestplate'in kopyası

Tüm bu sınıflar (Helmet, Chestplate, Greaves, Boots) tamamen aynı. Ne yeni nitelik ne de yeni davranış ekliyorlar. Sadece super().__init__ çağrısı yapıyorlar.

OOP, dünyadaki her fiziksel nesneyi ayrı bir sınıfla tanımlamak için yaratılmadı. Varlıklar yalnızca kategori adıyla farklılık gösteriyorsa, bu tek bir Armor sınıfı olmalı ve slot_type niteliğine sahip olmalıdır (ideal olarak Enum ile).

2️⃣ Frankenstein yapıcısı
Bir öğenin nasıl oluşturulduğuna bakın:
crown = Helmet('Şlem Gospodstva', 'Şlem', 'Sila', 5, 'Lovkost', 7, 'İntellekt', 3)

Asla stat adlarını yöntem imzasına sabit kodlamayın. Sözlük kullanın.
Bu parametre karmaşası yerine, öğe stats={'strength': 5, 'agility': 7, 'intellect': 3} almalıdır.

3️⃣ Sınıf ensesti
Characteristic sınıfı hero alıyor ve sonra şunu yapıyor:
for item in self._hero.slots_equipment.values():
if item:
if hasattr(item, 'value_strength') and item.value_strength:
self.attributes['strength'] += item.value_strength

Buna "Tight Coupling" (sıkı bağlılık) denir. Özellik sınıfı, kahramanın envanterine kirli ellerle dalıyor, öğelerin olup olmadığını kontrol ediyor ve ardından hasattr (ki bu vakaların %99'unda bir koltuk değneğidir) ile statları çekmeye çalışıyor.

Kahraman, kendi ekipmanını sorgulamalı ve nihai değiştiricileri özellik sistemine iletmelidir. Şu anda kuyruk köpeği sallıyor.

4️⃣ Mantık için İstisnalar Kullanımı
equip_armor yönteminde şunu görüyoruz:
try:
if key not in self.slots_equipment:
print('Böyle bir yuva yok.')
# ... mantık ...
except KeyError:
print(f'Öğe bulunamadı')

Birincisi, geniş KeyError yakalaması, kodunuzdaki gerçek hataları (örneğin, try içindeki bir sözlükte yazım hatası) gizler. İkincisi, istisnalar istisnai durumlar içindir, envanterde öğe olup olmadığını kontrol etmek için değil. Bunun için sözlüğün .get() yöntemi var.

Genel olarak, başlangıç ​​için 10 işe yaramaz zırh sınıfı ve canavar yapıcılar yerine en azından şöyle yapılabilir:

from dataclasses import dataclass
from enum import Enum

class EquipmentSlot(Enum):
HEAD = "Kask"
CHEST = "Göğüslük"
WEAPON = "Silah"

@dataclass
class Equipment:
name: str
slot: EquipmentSlot
stats_bonus: dict[str, int]

# Öğe oluşturma:
crown = Equipment(
name='Hüküm Kaskı',
slot=EquipmentSlot.HEAD,
stats_bonus={'strength': 5, 'agility': 7, 'intellect': 3}
)

Ve hepsi bu. Kod tekrarı yok, Enum ile yuvalarda yazım hatası koruması ve yarın "Şans" eklemek istediğinizde onlarca sınıfın __init__ini yeniden yazmanız gerekmeyen genişletilebilir bir stat sistemi.

OOP, evrendeki her varlık için ayrı bir sınıfınız olması değildir. OOP, karmaşıklığı ve durumu yönetmekle ilgilidir.


Ancak bir aylık öğrenim için bu kesinlikle normal bir evrim aşamasıdır.

📖 Okuyun:
- Python'da Sınıf Ne Zaman Kötüdür: Hayatınızı Zorlaştırdığınız 6 Durum
- Python Örnekleriyle OOP'de SOLID Prensipleri