Aikido

Dosya başına neden bir sınıf kullanmalısınız: kod organizasyonunu ve gezinmeyi iyileştirme

Okunabilirlik

Kural

Bir dosyada bir sınıf.
Tek bir dosyada birden fazla sınıf bulunması, kod
organizasyonunu belirsizleştirir ve kodda gezinmeyi zorlaştırır.

Desteklenen diller: 45+

Giriş

Birden fazla sınıfın tek bir dosyaya konulması, kod tabanında gezinirken belirli sınıfları bulmayı zorlaştırır. Arayan geliştiriciler UserRepository öğesini, beş başka sınıfla birlikte şu adlı bir dosyanın içinde gömülü kalmışsa hızlıca bulamaz: database.js adı verilen dosya. Bu durum en az şaşırtma ilkesini (principle of least surprise) ihlal eder ve ekip üyeleri sınıf tanımlarını aramakla vakit kaybettiği için geliştirme sürecini yavaşlatır.

Neden önemli?

Kod sürdürülebilirliği: Dosya başına birden fazla sınıf, sorumluluklar arasında belirsiz sınırlar oluşturur. Bir sınıfın değiştirilmesi gerektiğinde geliştiriciler, ilişkisiz sınıfları içeren bir dosyayı açmak zorunda kalır; bu da Bilişsel yükü ve yanlış kodu kazara değiştirme riskini artırır.

Gezinme ve keşfedilebilirlik: Birden fazla sınıf aynı dosyayı paylaştığında IDE'ler ve metin düzenleyiciler doğru "tanıma git" (go to definition) işlevini sağlamakta zorlanır. Geliştiriciler ihtiyaç duydukları sınıfa doğrudan atlamak yerine dosya içinde arama yaparak zaman harcar. Bu durum, yüzlerce sınıfın bulunduğu büyük kod tabanlarında katlanarak artar.

Sürüm kontrol çakışmaları: Birden fazla sınıf aynı dosyayı paylaştığında, farklı geliştiricilerin farklı sınıflarda yaptığı değişiklikler birleştirme (merge) çakışmalarına yol açar. Ayrı dosyalar, her geliştirici kendi dosyasında çalıştığı için koordinasyon yükü olmadan paralel geliştirmeyi mümkün kılar.

Kod örnekleri

❌ Kural dışı:

// database.js
class UserRepository {
    async findById(id) {
        return db.users.findOne({ id });
    }
}

class OrderRepository {
    async findByUser(userId) {
        return db.orders.find({ userId });
    }
}

class ProductRepository {
    async findInStock() {
        return db.products.find({ stock: { $gt: 0 } });
    }
}

module.exports = { UserRepository, OrderRepository, ProductRepository };

Neden yanlış: Şu isimli tek bir dosyada ilişkisiz üç repository sınıfı database.js. Şunu aramak OrderRepository öğesini bulmak, bunun yerine database.js içinde değil OrderRepository.jsiçinde olduğunu bilmeyi gerektirir. Dosya değişiklikleri birden fazla sınıfı etkileyerek gereksiz birleştirme çakışmaları yaratır.

✅ Kurallara uygun:

// UserRepository.js
class UserRepository {
    async findById(id) {
        return db.users.findOne({ id });
    }
}
module.exports = UserRepository;

// OrderRepository.js
class OrderRepository {
    async findByUser(userId) {
        return db.orders.find({ userId });
    }
}
module.exports = OrderRepository;

// ProductRepository.js
class ProductRepository {
    async findInStock() {
        return db.products.find({ stock: { $gt: 0 } });
    }
}
module.exports = ProductRepository;

Neden önemli: Her sınıfın kendi dosyasında olması gezinmeyi öngörülebilir kılar. IDE'ler bir sınıf aranırken doğrudan şuraya atlayabilir: OrderRepository.js . Bir repository'de yapılan değişiklikler diğerlerini etkilemez ve gereksiz birleştirme çakışmalarını ortadan kaldırır.

Sonuç

Öngörülebilir bir gezinme için dosyaları içerdikleri sınıflara göre adlandırın. Bu kural, belirli sınıfları hızlıca bulmanın önemli olduğu büyük kod tabanlarında ölçeklenebilirdir. Ekstra dosyalar, sağladıkları organizasyonel netliğe fazlasıyla değer.

Sık Sorulan Sorular

Sorularınız mı var?

Küçük yardımcı sınıflar (helper classes) veya özel sınıflar (private classes) ne olacak?

Yalnızca bir üst sınıf tarafından kullanılan küçük yardımcı sınıflar, eğer gerçekten birer uygulama detayıysalar aynı dosyada kalabilir. Ancak yardımcılar yeniden kullanılıyorsa veya 20-30 satırı aşıyorsa bunları dışarı çıkarın. Yalnızca bir genel (public) sınıfı desteklemek için var olan özel sınıflar makul istisnalardır.

Bu durum TypeScript arayüzleri (interfaces) ve tipleri (types) için de geçerli mi?

Bir sınıf tarafından kullanılan tipler ve arayüzler aynı dosyada bulunabilir. Ancak, birden fazla dosyada kullanılan paylaşımlı tipler kendi tip tanımı dosyalarında yer almalıdır. Buradaki temel ölçüt, tanımın yalnızca o dosya tarafından mı kullanıldığı yoksa başka yerlerde de mi gerektiğidir.

Standart uygulamada birden fazla sınıf içeren Python gibi dillerde durum nedir?

Python kuralları farklılık gösterir, ancak ilke yine geçerlidir: birbiriyle uyumlu bir modül oluşturuyorlarsa ilgili sınıfları gruplandırın, ancak ilişkisiz sınıfları karıştırmaktan kaçının. User ve UserProfile içeren bir models.py mantıklıdır. Yirmi ilişkisiz sınıf içeren bir utils.py ise mantıklı değildir.

Üst (parent) ve alt (child) sınıflar gibi ilişkili sınıfları nasıl organize etmeliyim?

Bunları aynı dizin içinde ayrı dosyalara koyun. Animal ve Dog için animals/Animal.js ve animals/Dog.js kullanın. Dizin yapısı, dosya başına bir sınıf kuralını korurken ilişkileri de gösterir. Bu yaklaşım, ilişkili sınıfları tek bir dosyada toplamaya kıyasla daha iyi ölçeklenir.

Sınıfları ayırmak çok sayıda küçük dosya oluşturursa ne olacak?

Çok sayıda küçük dosya, az sayıda büyük dosyadan her zaman daha iyidir. Modern IDE'ler binlerce dosyayı sorunsuz bir şekilde yönetebilir. Dosya sisteminde gezinmek, büyük dosyalar içinde arama yapmaktan daha hızlıdır. Her sınıfın tam olarak nerede olduğunu bilmenin netliği, "çok fazla dosya" algısından daha ağır basar.

Şimdi güvenliğinizi sağlayın

Kodunuzu, bulutunuzu ve çalışma zamanınızı tek bir merkezi sistemde güvenceye alın.
Güvenlik açıklarını otomatik olarak hızla bulun ve düzeltin.

Kredi kartı gerekmez | Tarama sonuçları 32 saniyede.