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