10

因此,对于试图理解类的人来说,这更像是一个哲学问题。

大多数时候,我如何使用类实际上是一种非常糟糕的使用方式。我想到了很多函数,一段时间后只是缩进代码并使其成为一个类,如果一个变量重复很多,用 self.variable 替换一些东西。(我知道这是不好的做法)但无论如何......我要问的是:

 class FooBar:
       def __init__(self,foo,bar):
           self._foo = foo
           self._bar = bar
           self.ans = self.__execute()

       def __execute(self):
            return something(self._foo, self._bar)

现在有很多方法可以做到这一点:

   class FooBar:
         def __init__(self,foo):
           self._foo = foo


       def execute(self,bar):
            return something(self._foo, bar)

你能建议哪个不好,哪个更糟吗?

或任何其他方式来做到这一点。

这只是一个玩具示例(offcourse)。我的意思是,如果有一个函数,这里就不需要有一个类.. 但是让我们说 __execute something() 调用一整套其他方法.. ?? 谢谢

4

2 回答 2

9

如果每个FooBar人都负责,bar那么第一个是正确的。如果bar只需要execute()而不是FooBar的问题,则第二个是正确的。

于 2012-09-12T15:32:47.443 回答
4

一句话,您在这里要担心的正式术语是Separation of Concerns

In response to your specific example, which of the two examples you choose depends on the concerns solved by FooBar and bar. If bar is in the same problem domain as FooBar or if it otherwise makes sense for FooBar to store a reference to bar, then the second example is correct. For instance, if FooBar has multiple methods that accept a bar and if you always pass the same instance of bar to each of a particular FooBar instance's bar-related methods, then the prior example is correct. Otherwise, the latter is more correct.

Ideally, each class you create should model exactly one major concern of your program. This can get a bit tricky, because you have to decide the granularity of "major concern" for yourself. Look to your dependency tree to determine if you're doing this correctly. It should be relatively easy to pull each individual class out of your program and test it in isolation from all other classes. If this is very difficult, you haven't split your concerns correctly. More formally, good separation of concerns is accomplished by designing classes which are cohesive and loosely coupled.

While this isn't useful for the example you posted, one simple pattern that helps accomplish this on a broader scale is Inversion of Control (IoC, sometimes called Dependency Injection). Under IoC, classes are written such that they aren't aware of their dependencies directly, only the interfaces (protocols in Python-speak) which their dependencies implement. Then at run time, typically during application initialization, instances of major classes are created by factories, and they are assigned references to their actual dependencies. See this article (with this example) for an explanation of how this can be accomplished in Python.

Finally, learn the four tenets of object-oriented programming.

于 2012-09-12T15:51:49.137 回答