了解所有基类的实现

时间:2018-08-13 22:06:28

标签: python design-patterns

问题:

我正在尝试使用python模拟一个Boids粒子系统,这是我为Blender 3D创建的一个插件,这相当复杂,将从头开始。

这是我第三次尝试为其设计可维护的代码结构。

我试图提出pythonic设计,该设计允许对彼此相互作用的不同类别的粒子进行快速原型制作,这样我就可以创建一个新的粒子实现,并使它与系统中的其他粒子进行交互。 / p>

请参见示例:

class ParticleSystem:
    def __init__(self):
        self.particles = []

    def add_particle(self, particle):
        self.particles.append(particle)

    def step_frame(self, speed):
        for p in self.particles:
            p.step(speed)


 class Particle:
    def __init__(self, system)
        self.location = Vector(0,0,0)
        self.system = system

    def step(speed):
        for particle in self.system.particles:
            #random interatcion formula
            self.location = particle.location + self.location


system = ParticleSystem()

p = Particle(system)
system.add_particle(p)

您可以看到这是我最好的方法,但是当我有多个类别的粒子并且必须将系统传递给粒子然后再将粒子传递给系统时,它会变得非常混乱。

问题

有没有一种方法可以让我检测何时创建类似Class Baseball(Particle):的类实现,并使系统类知道所有现有类型,因此我可以调用system.create_baseball(location)

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用Particle的{​​{1}}方法。

您可以这样定义__subclasses__

ParticleSystem

也就是说,避免让不同的类了解彼此的内部运作通常是一个好主意。 class ParticleSystem(object): def __init__(self): self.particles = [] def create_particle(self, particle_type, location): if particle_type in (cls.__name__ for cls in Particle.__subclasses__()): p = eval(particle_type)(self) p.location = location self.particles.append(p) else: raise TypeError("{} is not a subclass of Particle".format(particle_type)) 是否真的需要知道ParticleSystem的所有子类(更好-每个粒子是否需要知道它所在的系统?)?还是只需要一种简单的方法来实例化新的Particle对象?如果仅需要后者,则可以使用simple factory method

注意:使用Particle通常有点鲁ck,但是由于受eval条件的保护,所以应该没事。