팩토리 패턴
Coddy Python 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 64개 중 46번째.
팩터리 패턴은 정확한 클래스를 지정하지 않고 객체를 생성합니다. 생성자를 직접 호출하는 대신, 어떤 클래스를 인스턴스화할지 결정하는 팩터리 메서드를 사용합니다.
다음은 간단한 제품 클래스입니다:
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}"이러한 객체를 생성하는 팩터리 클래스를 만드세요:
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}")객체가 필요한 코드를 클라이언트 코드라고 합니다. 생성자를 직접 호출하는 대신 팩토리에 요청합니다:
factory = VehicleFactory()
my_car = factory.create_vehicle("car", "Toyota")
my_bike = factory.create_vehicle("bike", "Honda")
print(my_car.info()) # 자동차: Toyota
print(my_bike.info()) # 오토바이: Honda*args를 사용하여 팩토리를 더 유연하게 만들어 보세요:
class FlexibleFactory:
def create_vehicle(self, vehicle_type, *args):
if vehicle_type == "car":
return Car(args[0]) # 브랜드만
elif vehicle_type == "truck":
return Truck(args[0], args[1]) # 브랜드와 적재 용량
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)"유연한 팩토리를 사용합니다:
flexible = FlexibleFactory()
car = flexible.create_vehicle("car", "Ford")
truck = flexible.create_vehicle("truck", "Volvo", "20")
print(car.info()) # 자동차: Ford
print(truck.info()) # 트럭: Volvo (20t)출력:
Car: Toyota
Bike: Honda
Car: Ford
Truck: Volvo (20t)핵심 요점: 팩토리 패턴을 사용하면 정확한 클래스를 몰라도 객체를 생성할 수 있습니다. 팩토리 메서드는 매개변수를 기반으로 어떤 클래스를 인스턴스화할지 결정합니다. 생성자 매개변수가 서로 다른 제품을 처리하려면 *args를 사용하세요. 이렇게 하면 코드를 더 유연하게 만들고 새로운 제품 유형으로 더 쉽게 확장할 수 있습니다.
챌린지
중급이 챌린지에서는 상속과 다형성을 활용한 적절한 객체 지향 설계로 도형 팩토리 시스템을 구현합니다.
다음 파일의 구현을 완성하세요.
shape.py- 기본 Shape 클래스circle.py- Circle 구현rectangle.py- Rectangle 구현triangle.py- Triangle 구현shapefactory.py- 도형을 생성하는 팩토리 클래스
각 파일에는 구현을 안내하는 자세한 TODO 주석이 있습니다. 코드가 모든 요구 사항을 충족하도록 주석을 주의 깊게 따르세요.
직접 해보기
from shapefactory import ShapeFactory
from shape import Shape
from circle import Circle
from rectangle import Rectangle
from triangle import Triangle
import sys
# 테스트 케이스 실행기
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)
# 구현을 비교하기 위해 메서드 객체 가져오기
circle_area = Circle.area
rectangle_area = Rectangle.area
triangle_area = Triangle.area
circle_perimeter = Circle.perimeter
rectangle_perimeter = Rectangle.perimeter
triangle_perimeter = Triangle.perimeter
# 모든 구현이 서로 다른지 확인하기
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")이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Python 컴파일러