英文:
Fixing Abstract Factory in Python
问题
I'm trying to implement Abstract Factory pattern in Python, but after creating new "product" it simply does not work and I can't figure out what's the problem. Here's a code:
from __future__ import annotations
from abc import ABC, abstractmethod
# AbstractFactory
class AbstractCarFactory(ABC):
@abstractmethod
def create_product_car(self) -> AbstractProductCar:
pass
@abstractmethod
def create_product_engine(self) -> AbstractProductEngine:
pass
@abstractmethod
def create_product_wheel(self) -> AbstractProductWheel:
pass
class FordFactory(AbstractCarFactory):
def create_product_car(self) -> AbstractProductCar:
return Ford()
def create_product_engine(self) -> AbstractProductEngine:
return FordEngine()
def create_product_wheel(self) -> AbstractProductWheel:
return FordWheel()
# ... (rest of the code)
if __name__ == "__main__":
print("Client: Testing first factory:")
client_code(FordFactory())
print("Client: Testing second factory:")
client_code(ToyotaFactory())
print("Client: Testing third factory:")
client_code(MercedesFactory())
I've already tried to create abstract client code instead of copying it every time but it doesn't help. Even ChatGPT can't tell what's the matter lol
英文:
I'm trying to implement Abstract Factory pattern in Python, but after creating new "product" it simply does not work and I can't firuge out what's the problem. Here's a code:
`from __future__ import annotations
from abc import ABC, abstractmethod
# AbstractFactory
class AbstractCarFactory(ABC):
@abstractmethod
def create_product_car(self) -> AbstractProductCar:
pass
@abstractmethod
def create_product_engine(self) -> AbstractProductEngine:
pass
@abstractmethod
def create_product_wheel(self) -> AbstractProductWheel:
pass
class FordFactory(AbstractCarFactory):
def create_product_car(self) -> AbstractProductCar:
return Ford()
def create_product_engine(self) -> AbstractProductEngine:
return FordEngine()
def create_product_wheel(self) -> AbstractProductWheel:
return FordWheel()
class ToyotaFactory(AbstractCarFactory):
def create_product_car(self) -> AbstractProductCar:
return Toyota()
def create_product_engine(self) -> AbstractProductEngine:
return ToyotaEngine()
def create_product_wheel(self) -> AbstractProductWheel:
return ToyotaWheel()
class MercedesFactory(AbstractCarFactory):
def create_product_car(self) -> AbstractProductCar:
return Mercedes()
def create_product_engine(self) -> AbstractProductEngine:
return MercedesEngine()
def create_product_wheel(self) -> AbstractProductWheel:
return MercedesWheel()
class AbstractProductCar(ABC):
@abstractmethod
def info_car(self) -> str:
pass
def interact1_car(self, collaborator: AbstractProductEngine) -> str:
pass
def interact2_car(self, collaborator: AbstractProductWheel) -> str:
pass
class AbstractProductEngine(ABC):
@abstractmethod
def get_power(self) -> str:
pass
class FordEngine(AbstractProductEngine):
def get_power(self) -> str:
return "Ford Engine"
class ToyotaEngine(AbstractProductEngine):
def get_power(self) -> str:
return "Toyota Engine"
class MercedesEngine(AbstractProductEngine):
def get_power(self) -> str:
return "Mercedes Engine"
class AbstractProductWheel(ABC):
@abstractmethod
def get_wheel(self) -> str:
pass
class FordWheel(AbstractProductWheel):
def get_wheel(self) -> str:
return "Ford Wheel"
class ToyotaWheel(AbstractProductWheel):
def get_wheel(self) -> str:
return "Toyota Wheel"
class MercedesWheel(AbstractProductWheel):
def get_wheel(self) -> str:
return "Mercedes Wheel"
class Ford(AbstractProductCar):
def info_car(self) -> str:
return "Ford"
def interact1_car(self, collaborator: AbstractProductEngine) -> str:
result1 = self.info_car() + " set Engine " + collaborator.get_power()
return f"Result of setting engine to the body: ({result1})"
def interact2_car(self, collaborator: AbstractProductWheel) -> str:
result2 = self.info_car() + " set Wheels " + collaborator.get_wheel()
return f"Result of final assembly: {result2}"
class Toyota(AbstractProductCar):
def info_car(self) -> str:
return "Toyota"
def interact1_car(self, collaborator: AbstractProductEngine) -> str:
result1 = self.info_car() + " set Engine " + collaborator.get_power()
return f"Result of setting engine to the body: ({result1})"
def interact2_car(self, collaborator: AbstractProductWheel) -> str:
result2 = self.info_car() + "set Wheels " + collaborator.get_wheel()
return f"Result of final assembly: {result2}"
class Mercedes(AbstractProductCar):
def info_car(self) -> str:
return "Mercedes"
def interact1_car(self, collaborator: AbstractProductEngine) -> str:
result1 = self.info_car() + " set Engine " + collaborator.get_power()
return f"Result of setting engine to the body: ({result1})"
def interact2_car(self, collaborator: AbstractProductWheel) -> str:
result2 = self.info_car() + "set Wheels " + collaborator.get_wheel()
return f"Result of final assembly: {result2}"
def client_code(factory: AbstractCarFactory) -> None:
product_a = factory.create_product_car()
product_b = factory.create_product_engine()
print(f"{product_a.interact1_car(product_b)}"
f"{product_a.interact2_car(product_b)}")
if __name__ == "__main__":
print("Client: Testing first factory:")
client_code(FordFactory())
print("Client: Testing second factory:")
client_code(ToyotaFactory())
print("Client: Testing third factory:")
client_code(MercedesFactory())
I've already tried to create abstract client code instead of copying it every time but it doesn't help. Even ChatGPT can't tell what's te matter lol
答案1
得分: 1
I'm providing the translated content:
我假设你发送的代码在复制和粘贴时缩进不正确,因为许多类的方法与类定义嵌套在一起。在修复后,我运行了你的代码并得到以下结果:
python3 test.py
Client: Testing first factory:
NoneNone
Client: Testing second factory:
Traceback (most recent call last):
File "/Users/jamied/git/pseudocode/test.py", line 157, in <module>
client_code(ToyotaFactory())
File "/Users/jamied/git/pseudocode/test.py", line 149, in client_code
f"{product_a.interact2_car(product_b)}"
File "/Users/jamied/git/pseudocode/test.py", line 127, in interact2_car
result2 = self.info_car() + "set Wheels " + collaborator.get_wheel()
AttributeError: 'ToyotaEngine' object has no attribute 'get_wheel'
看起来你创建的第二个方法 interact2_car
似乎是要与 AbstractProductWheel
类交互,但你给它了一个 AbstractProductEngine
类。也许这才是你的本意?
def client_code(factory: AbstractCarFactory) -> None:
product_a = factory.create_product_car()
product_b = factory.create_product_engine()
product_c = factory.create_product_wheel() # 我添加了这一行
print(f"{product_a.interact1_car(product_b)}"
f"{product_a.interact2_car(product_c)}") # 现在使用 product c
然后运行这段代码会得到以下结果:
python3 test.py
Client: Testing first factory:
Result of setting engine to the body: (Ford set Engine Ford Engine)Result of final assembly: Ford set Wheels Ford Wheel
Client: Testing second factory:
Result of setting engine to the body: (Toyota set Engine Toyota Engine)Result of final assembly: Toyotaset Wheels Toyota Wheel
Client: Testing third factory:
Result of setting engine to the body: (Mercedes set Engine Mercedes Engine)Result of final assembly: Mercedesset Wheels Mercedes Wheel
这希望是你想要的结果。
附注:通常在提问类似问题时附上错误消息会有助于更容易看到问题所在。
英文:
I'm assuming the code you've sent was indented incorrectly when copying and pasting as a lot of the methods for classes are inline with the class definition. After fixing that I ran your code and got:
python3 test.py
Client: Testing first factory:
NoneNone
Client: Testing second factory:
Traceback (most recent call last):
File "/Users/jamied/git/pseudocode/test.py", line 157, in <module>
client_code(ToyotaFactory())
File "/Users/jamied/git/pseudocode/test.py", line 149, in client_code
f"{product_a.interact2_car(product_b)}")
File "/Users/jamied/git/pseudocode/test.py", line 127, in interact2_car
result2 = self.info_car() + "set Wheels " + collaborator.get_wheel()
AttributeError: 'ToyotaEngine' object has no attribute 'get_wheel'
It looks like the second method you created interact2_car
was meant to interact with a AbstractProductWheel
class but instead you gave it a AbstractProductEngine
class. Maybe this is what you meant to do?
def client_code(factory: AbstractCarFactory) -> None:
product_a = factory.create_product_car()
product_b = factory.create_product_engine()
product_c = factory.create_product_wheel() # I added this
print(f"{product_a.interact1_car(product_b)}"
f"{product_a.interact2_car(product_c)}") # now using product c
Then running this gives
python3 test.py
Client: Testing first factory:
Result of setting engine to the body: (Ford set Engine Ford Engine)Result of final assembly: Ford set Wheels Ford Wheel
Client: Testing second factory:
Result of setting engine to the body: (Toyota set Engine Toyota Engine)Result of final assembly: Toyotaset Wheels Toyota Wheel
Client: Testing third factory:
Result of setting engine to the body: (Mercedes set Engine Mercedes Engine)Result of final assembly: Mercedesset Wheels Mercedes Wheel
Which is hopefully what you wanted?
ps. it's usually helpful to post the error message when asking a question like this, it makes it easier to see what the problem is.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论