本课程中的信息似乎是 OOP 围绕代码组织而不是为了可重复方差而创建类。
例如:第23天是青蛙游戏。 讲师创建一个“CarManager”类,该类一遍又一遍地生成同一辆车。 除了代码组织之外,似乎没有任何理由不能将 CarManager 函数放置在 main.py 文件中。
问题:
在青蛙游戏示例中,我对教练的做法采取了不同的方法(代码如下)。 我创建了一个 Car 类,其中包含大小和速度的输入。然后在我的 main.py 代码中,我使用 Car 类(摩托车、汽车、卡车、半挂车)生成了 4 种不同尺寸和速度的不同车辆。 这不是在 Python 中使用 OOP 更合适吗?
汽车类别:
from turtle import Turtle
import random
CAR_COLORS = ["blue", "red", "black", "green", "pink", "orange"]
class Car:
def __init__(self, size1, speed1):
self.car_pieces = []
self.car_list = []
self.create_car(size1)
self.speed = speed1
def create_car(self, car_size):
color2 = random.choice(CAR_COLORS)
xcor = random.randrange(310, 350, 20)
ycor = random.randrange(-235, 226, 40)
for i in range(car_size):
car_piece = Turtle()
car_piece.color(color2)
car_piece.shape("square")
car_piece.penup()
car_piece.setposition(xcor, ycor)
self.car_pieces.append(car_piece)
xcor += 20
def car_move(self):
for i in range(len(self.car_pieces)):
self.car_pieces[i].backward(self.speed)
main.py
#Car generation
car_list = []
motorcycle_speed = 12
car_speed = 5
truck_speed = 3
semi_speed = 1
def car_generator():
car_options = ["motorcycle", "car", "truck", "semi"]
car_choice = random.choice(car_options)
random_chance = random.randint(1,6)
if random_chance == 1:
if car_choice == "motorcycle":
motorcycle_object = Car(1, motorcycle_speed)
car_list.append(motorcycle_object)
elif car_choice == "car":
car_object = Car(2, car_speed)
car_list.append(car_object)
elif car_choice == "truck":
truck_object = Car(3, truck_speed)
car_list.append(truck_object)
elif car_choice == "semi":
semi_object = Car(4, semi_speed)
car_list.append(semi_object)
else:
pass
有很多可能的“正确”和“不正确”的编程方式。
正如您所说,OOP 的目标是构建您的代码,以便在您收回代码来编写新功能时不会失去理智。实际上,OOP 对于代码设计非常有用,例如,观看设计模式和 SOLID 架构...
但这不是唯一的原因。假设您将来想实现“警察”或“自行车”等新功能。实际上,您显然可以创建一个类并从 main.py 调用该类。但是,当您实现很多这些功能时,您实际上将拥有一个庞大的函数,它调用不同模块中的不同类,并且每次如果类编写得不好,您都必须修改这些模块之一。
您可以遵循的最佳原则是单一职责(SOLID架构的S),这意味着一个函数具有一个职责,因此如果car_generator是一个生成汽车的函数,实际上不应该生成自行车。这样,当您再次阅读代码时,您就会知道 car_generator 没有实现自行车。
现在,您可能会想“好吧,我将 generator 中的 car_generator 重命名,然后我解决了问题”。其实你可以,但要点是生成器必须只做一件事。当您在 generator 中添加代码来检查特定时间内游戏中有多少车辆时,您就打破了这一原则,并且在 3 个月内您会忘记您在此函数中添加了此功能。
现在重新阅读你的代码并思考“这个函数实际上只做了一件事吗?”,如果答案是肯定的,你可以过去,但如果将来你编程来实现车辆计数器,你必须管理事实上 car_generator 实际上已经做了一件事,它创造了车辆。
您也可以将这一事实扩展到模块。 main.py 实际上就像一个 wizard 。它必须调用其他函数并维护游戏中的“逻辑”。显然,您可以在其中实例化对象,但是如果有一天您将拥有 twen0 个类,每个类创建 twen0 车辆怎么办?
问题是 car_generator 更多的是一个生成 car 的函数,所以它不应该留在 main.py 中。这样,当您认为“好吧,我必须创建一辆车”时,您知道您必须访问并修改 Car.py 而不是 main.py。
另一件事是,实际上你正在用 C 语言“思考”。开始编程是真的很酷,但实际上 OOP 是继承和多态性的伟大原因。
我重复:您的解决方案实际上并不是“明显错误”或“明显好”。取决于您接下来要实施的内容。如果课程教你这一点,可能是因为导师经过多年的编码后发现这是创建此类事物的最清晰、最美丽的方式。我建议你阅读书籍并观看干净代码和设计模式的在线教程,以了解你的老师“隐含地说”的内容
问候