有时使用带有多重继承的 mixin 可以帮助我们提高代码的可重用性。
例如,以下设计
class FollowableMixin(object):
def get_followers(self):
...
...
class User(FollowableMixin):
...
可以更好地重复使用,而不是简单地将get_followers
添加到User
:
class User(object):
def get_followers(self):
...
...
因为稍后我们可能会考虑支持作为get_followers
潜在客户的其他可跟随实体:
class BookStore(FollowableMixin):
...
但是,如果过度使用此模式,代码可能会过于复杂。
class User(FollowableMixin, RunnableMixin, FlyableMixin, WhatMixin ...):
...
通过所有这些mixin类为您的类注入属性和方法,理解您的代码变得非常困难。例如,您不知道您调用的方法来自何处,并且此方法可能反过来包括在另一个mixin中调用方法...
我该怎么做才能简化这个程序?
答案 0 :(得分:6)
如果它们经常一起使用,有时可以帮助在一个类中收集相关功能。
class FooMixin(FollowableMixin, RunnableMixin):
pass
然后当你使用它时,你只有一个或两个直接基类而不是很多。
显然你应该只在有意义的情况下这样做 - 它可能被滥用。如果不了解您的具体示例,很难知道在您的情况下是否有意义。
答案 1 :(得分:6)
如果您的User类确实具有适当的许多特性,那么您可能只是拥有一个复杂的应用程序。有五个mixin比从其他地方复制五个函数更好。
简化的一些可能性:
您的用户类正在尝试做太多。把它分成更小的类。
汇总一些mixin。例如,您可能会发现有五个类,每个类都是Followable,Runnable和Flyable。创建一个从这三个mixin派生的中间类FollowRunFly,然后在五个类中使用FollowRunFly。
也许你不必如此精细地切割你的mixins。制作一个大的mixin,并在你的类上使用它,让代码在运行时确定对象是否可以飞行或被跟踪。
答案 2 :(得分:4)
使用适配器而不是mixins。因此,在您的情况下,您将拥有一个IFollowable接口和从BookStore或User到IFollowable的适配器。
有关Python中适配器的一个描述,请参阅http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/,特别是Martijn Faassen关于使用工厂和接口以及grokcore.component
的注释。
答案 3 :(得分:3)
使用纸和笔,记下实际获得实例化的具体类(例如User和BookStore)。列出您希望这些类执行的所有方法。只有通过查看此列表,您才能合理地确定哪种类层次最适合您的情况。手写的缓慢可能会迫使您以新的方式思考对象之间的关系。尝试向一位聪明但对你的问题一无所知的想象中的朋友(或我们!)详细解释你的课程。阐明细节的缓慢可能会带来洞察力。
Mixins可能会给你很多普遍性,让你的项目成长,但你经常被迫在一般性(复杂性)和实用性(通常更简单)之间做出妥协。四个mixin允许2 ** 4个可能的具体类。如果在实践中你的混凝土类别少得多,那么mixin可能不适合这项工作。
如果你觉得这种普遍性让你感到压倒一切,我认为以最简单的方式支持这些功能是明智之举,冻结功能和编码。然后,当您有一个可用的产品时,您可以考虑添加新功能,并在必要时进行重构。