Factory Kalıbı
Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 46 / 64.
Factory Deseni, nesneleri tam sınıflarını belirtmeden oluşturur. Yapıcıları (constructors) doğrudan çağırmak yerine, hangi sınıfın örnekleneceğine karar veren bir fabrika yöntemi (factory method) kullanırsınız.
İşte basit ürün sınıfları:
class Car:
def __init__(self, brand):
self.brand = brand
self.type = "Car"
def info(self):
return f"{self.type}: {self.brand}"
class Bike:
def __init__(self, brand):
self.brand = brand
self.type = "Bike"
def info(self):
return f"{self.type}: {self.brand}"Bu nesneleri üretmek için bir fabrika sınıfı oluşturun:
class VehicleFactory:
def create_vehicle(self, vehicle_type, brand):
if vehicle_type == "car":
return Car(brand)
elif vehicle_type == "bike":
return Bike(brand)
else:
raise ValueError(f"Unknown type: {vehicle_type}")Yapıcıları doğrudan çağırmak yerine fabrikayı kullanın:
factory = VehicleFactory()
my_car = factory.create_vehicle("car", "Toyota")
my_bike = factory.create_vehicle("bike", "Honda")
print(my_car.info()) # Araba: Toyota
print(my_bike.info()) # Bisiklet: HondaFabrikayı *args kullanarak daha esnek hale getirin:
class FlexibleFactory:
def create_vehicle(self, vehicle_type, *args):
if vehicle_type == "car":
return Car(args[0]) # Sadece marka
elif vehicle_type == "truck":
return Truck(args[0], args[1]) # Marka ve kapasite
else:
raise ValueError(f"Unknown type: {vehicle_type}")
class Truck:
def __init__(self, brand, capacity):
self.brand = brand
self.capacity = capacity
self.type = "Truck"
def info(self):
return f"{self.type}: {self.brand} ({self.capacity}t)"Esnek fabrikayı kullanın:
flexible = FlexibleFactory()
car = flexible.create_vehicle("car", "Ford")
truck = flexible.create_vehicle("truck", "Volvo", "20")
print(car.info()) # Araba: Ford
print(truck.info()) # Kamyon: Volvo (20t)Çıktı:
Car: Toyota
Bike: Honda
Car: Ford
Truck: Volvo (20t)Anahtar Nokta: Fabrika Deseni (Factory Pattern), tam sınıflarını bilmeden nesneler oluşturmanıza olanak tanır. Fabrika yöntemi, parametrelere bağlı olarak hangi sınıfın örnekleneceğine karar verir. Farklı yapıcı (constructor) parametrelerine sahip ürünleri işlemek için *args kullanın. Bu, kodunuzu daha esnek hale getirir ve yeni ürün türleriyle genişletilmesini kolaylaştırır.
Görev
OrtaBu meydan okumada, kalıtım ve polimorfizm kullanarak uygun bir nesne yönelimli tasarıma sahip bir şekil fabrikası (shape factory) sistemi uygulayacaksınız.
Aşağıdaki dosyalardaki uygulamaları tamamlayın:
shape.py- Temel Shape sınıfıcircle.py- Circle uygulamasırectangle.py- Rectangle uygulamasıtriangle.py- Triangle uygulamasıshapefactory.py- Şekil oluşturmak için Fabrika (Factory) sınıfı
Her dosya, uygulamanıza rehberlik edecek ayrıntılı TODO yorumları içerir. Kodunuzun tüm gereksinimleri karşıladığından emin olmak için bu yorumları dikkatlice takip edin.
Kopya kağıdı
Factory Deseni, nesneleri tam sınıflarını belirtmeden oluşturur. Doğrudan yapıcıları (constructors) çağırmak yerine, hangi sınıfın örnekleneceğine karar veren bir fabrika yöntemi kullanırsınız.
Temel fabrika uygulaması:
class VehicleFactory:
def create_vehicle(self, vehicle_type, brand):
if vehicle_type == "car":
return Car(brand)
elif vehicle_type == "bike":
return Bike(brand)
else:
raise ValueError(f"Unknown type: {vehicle_type}")
# Kullanım
factory = VehicleFactory()
my_car = factory.create_vehicle("car", "Toyota")
my_bike = factory.create_vehicle("bike", "Honda")Farklı yapıcı parametreleri için *args kullanan esnek fabrika:
class FlexibleFactory:
def create_vehicle(self, vehicle_type, *args):
if vehicle_type == "car":
return Car(args[0]) # Sadece marka
elif vehicle_type == "truck":
return Truck(args[0], args[1]) # Marka ve kapasite
else:
raise ValueError(f"Unknown type: {vehicle_type}")
# Kullanım
flexible = FlexibleFactory()
car = flexible.create_vehicle("car", "Ford")
truck = flexible.create_vehicle("truck", "Volvo", "20")Temel avantajlar: Factory Deseni, mevcut istemci kodunu değiştirmeden kodu daha esnek hale getirir ve yeni ürün türleriyle genişletilmesini kolaylaştırır.
Kendin dene
from shapefactory import ShapeFactory
from shape import Shape
from circle import Circle
from rectangle import Rectangle
from triangle import Triangle
import sys
# Test durumu yürütücüsü
test_case = input()
factory = ShapeFactory()
if test_case == "circle_area":
circle = factory.create_shape("circle", 5)
print(f"{circle.area():.2f}")
elif test_case == "rectangle_perimeter":
rectangle = factory.create_shape("rectangle", 4, 6)
print(f"{rectangle.perimeter()}")
elif test_case == "triangle_perimeter":
triangle = factory.create_shape("triangle", 3, 4, 5)
print(f"{triangle.perimeter()}")
elif test_case == "invalid_shape":
try:
factory.create_shape("hexagon", 6)
print("No exception raised")
except ValueError as e:
print(str(e))
elif test_case == "case_insensitive":
circle = factory.create_shape("CiRcLe", 3)
print(f"{circle.area():.2f}")
elif test_case == "shape_inheritance":
shapes = [
factory.create_shape("circle", 2),
factory.create_shape("rectangle", 2, 3),
factory.create_shape("triangle", 3, 4, 5)
]
all_shapes = all(isinstance(shape, Shape) for shape in shapes)
print(all_shapes)
elif test_case == "zero_radius_circle":
circle = factory.create_shape("circle", 0)
print(f"{circle.area():.2f} {circle.perimeter():.2f}")
elif test_case == "negative_dimensions":
rectangle = factory.create_shape("rectangle", -2, -3)
print(f"{rectangle.area()}")
elif test_case == "large_values":
circle = factory.create_shape("circle", 1000000)
print(f"{circle.area():.2e}")
elif test_case == "polymorphism_test":
shapes = [
factory.create_shape("circle", 2),
factory.create_shape("rectangle", 3, 4),
factory.create_shape("triangle", 3, 4, 5)
]
area_sum = sum(shape.area() for shape in shapes)
perimeter_sum = sum(shape.perimeter() for shape in shapes)
print(f"Area sum: {area_sum:.2f}, Perimeter sum: {perimeter_sum:.2f}")
elif test_case == "triangle_area":
triangle = factory.create_shape("triangle", 3, 4, 5)
print(f"{triangle.area():.2f}")
elif test_case == "method_override":
circle = factory.create_shape("circle", 2)
rectangle = factory.create_shape("rectangle", 3, 4)
triangle = factory.create_shape("triangle", 3, 4, 5)
# Uygulamaları karşılaştırmak için metot nesnelerini al
circle_area = Circle.area
rectangle_area = Rectangle.area
triangle_area = Triangle.area
circle_perimeter = Circle.perimeter
rectangle_perimeter = Rectangle.perimeter
triangle_perimeter = Triangle.perimeter
# Tüm uygulamaların benzersiz olup olmadığını kontrol et
unique_areas = len({circle_area, rectangle_area, triangle_area}) == 3
unique_perimeters = len({circle_perimeter, rectangle_perimeter, triangle_perimeter}) == 3
if unique_areas and unique_perimeters:
print("All shapes correctly override methods")
else:
print("Some shapes share method implementations")Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerself ParametresiMetotlarÖzniteliklerYapıcı Metot (__init__)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımsuper() FonksiyonuMetot Geçersiz KılmaÇoklu KalıtımMetot Çözümleme SırasıÖzet - Çalışan Hiyerarşisi7Özel Metotlar
Sihirli Metotlara GirişOperatör Aşırı YüklemeKapsayıcı Sihirli MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım kalıplarına girişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı13Final Meydan Okumaları
E-öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi5Çok Biçimlilik (Polymorphism)
Metot Geçersiz Kılmaya Yeniden BakışDuck TypingSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon ve KalıtımMixinsStatik ve Sınıf MetotlarıSınıf DekoratörleriBağlam Yöneticileri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı