“Single Responsibility Principle” (SRP) Nedir?
“Single Responsibility Principle” (SRP), yazılım mühendisliğindeki SOLID prensiplerinin ilkidir ve bu prensiplerin temelini oluşturur. SRP, yazılım tasarımında “sorumluluk” kavramına odaklanır. Peki, bu sorumluluk nedir ve yazılım dünyasında neden bu kadar önemlidir? Detaylarıyla inceleyelim:
Single Responsibility Principle
Nasıl ki, hayatımızda öncelikli işlerimiz aynı zamanda bizim sorumluluklarımızı tanımlıyorsa, yazılım dünyasında da benzer bir durum geçerlidir. Bir sınıf veya modülün sorumluluğu, yazılım içerisindeki “iş”ini ya da “rolünü” ifade eder.
Eğer bir kişi birden fazla sorumluluk üstlenirse, dikkati dağılır ve verimliliği düşer. Yazılımda da bir sınıfın birden fazla sorumluluğu olduğunda benzer sorunlar ortaya çıkar. Kodun anlaşılması, bakımı ve genişletilmesi zorlaşır. İşte bu nedenle Single Responsibility Principle (SRP), her sınıfın yalnızca bir sorumluluğu olması gerektiğini öne sürer.
Bir sınıfın yalnızca bir sorumluluğa sahip olması yazılımın temiz, modüler ve esnek bir yapıya sahip olmasını sağlar. SRP’nin önemini anlamak için bir e-ticaret uygulamasını ele alalım.
SRP’ye Uygun Olmayan Kod
Aşağıdaki örnekte, ECommerceApplication sınıfı, kullanıcı arayüzü yönetimi, ödeme işlemleri ve veritabanı yönetimi gibi birçok farklı sorumluluğu üstlenmektedir:
class ECommerceApplication:
def __init__(self):
self.user_input = ""
self.payment_info = {}
self.user_data = {}
def get_input(self, input):
self.user_input = input
# Kullanıcı girdisini işler ve arayüzü günceller
return f"Arayüz güncellendi: {self.user_input}"
def process_payment(self, payment_info):
self.payment_info = payment_info
# Ödeme bilgisini işler ve doğrular
return f"Ödeme işlendi: {self.payment_info}"
def store_data(self, data):
self.user_data = data
# Veritabanına kullanıcı verilerini kaydeder
return f"Veri kaydedildi: {self.user_data}"
# Örnek kullanım
ecom_app = ECommerceApplication()
print(ecom_app.get_input("Kullanıcı girdisi"))
print(ecom_app.process_payment({"kart_numarası": "1234-5678-9101-1121", "tutar": 100}))
print(ecom_app.store_data({"kullanıcı_adı": "ali", "sipariş": "kitap"}))
Bu sınıf birçok işlevi yerine getirdiği için karmaşık hale gelmiştir. Eğer bir işlevi değiştirmek gerekirse, diğer işlevleri etkileyen değişikliklerin de yapılması gerekebilir. Bu da haliyle kodun bakımını zorlaştıracaktır.
SRP’ye uygun şekilde yeniden yazılmış kod:
class UserInterfaceManager:
def __init__(self):
self.user_input = ""
def get_input(self, input):
self.user_input = input
# Kod, kullanıcı girdisini işler ve arayüzü günceller
return f"Arayüz güncellendi: {self.user_input}"
class PaymentProcessor:
def __init__(self):
self.payment_info = {}
def process_payment(self, payment_info):
self.payment_info = payment_info
# Kod, ödeme bilgisini işler ve doğrular
return f"Ödeme işlendi: {self.payment_info}"
class DatabaseManager:
def __init__(self):
self.user_data = {}
def store_data(self, data):
self.user_data = data
# Kod, veritabanına kullanıcı verilerini kaydeder
return f"Veri kaydedildi: {self.user_data}"
# Örnek kullanım
ui_manager = UserInterfaceManager()
print(ui_manager.get_input("Kullanıcı girdisi"))
payment_processor = PaymentProcessor()
print(payment_processor.process_payment({"kart_numarası": "1234-5678-9101-1121", "tutar": 100}))
db_manager = DatabaseManager()
print(db_manager.store_data({"kullanıcı_adı": "ali", "sipariş": "kitap"}))
Sonuç olarak SRP, her sınıfın yalnızca tek bir sorumluluğa sahip olması gerektiğini öne sürerek, kodun düzenli, temiz ve sürdürülebilir bir yapıya sahip olmasını sağlar. Örneğimizde olduğu gibi, sınıfların net bir şekilde ayrılmasıyla, yazılımın bakımı ve genişletilmesi kolaylaşır. Bu yaklaşım, karmaşık projelerde hem geliştiricilerin işini kolaylaştırır hem de yazılımın uzun vadeli başarısını destekler.