折腾edX和Django Rest Framework的时候都看到Mixin的身影,决定弄清楚它。
##解释
Mixin即mix in,就是混入的意思。在不改变原对象的情况下对其进行扩展. 在运行期间,动态改变类的基类或类的方法
利用Mixin我们还可以增加无数总特征,而无需对已有代码作太大改动。实现无痛扩展
和多重继承类似.
但通常主类和 Mixin 类本身不是 is-a 的关系,混入 Mixin 类是为了添加某些(可选的)功能。自由地混入 Mixin 类就可以灵活地为被混入的类添加不同的功能。
传统的「接口」概念中并不包含实现,而 Mixin 包含实现。Mixin 提供了(默认)实现
wu:是为了额外获得方法?
Mixin的好处是可以为主类添加任意多的Mixin来实现多态
##QuickStart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class Fruit(object):
pass
class GiftMixin(object):
def is_gift_fruit(self):
return True
class NotGiftMixin(object):
def is_gift_fruit(self):
return False
class PareMixin(object):
def eat_method(self):
return 'Pare'
class HuskMixin(object):
def eat_method(self):
return 'Husk'
class Apple(GiftMixin, PareMixin, Fruit):pass
class Orange(GiftMixin, HuskMixin, Fruit):pass
class Pear(NotGiftMixin, PareMixin, Fruit):pass
class Banana(NotGiftMixin, HuskMixin, Fruit):pass
|
这样水果就知道自己的种类和特性啦
##何时用
There are two main situations where mixins are used:
- You want to provide a lot of optional features for a class.
- You want to use one particular feature in a lot of different classes.
摘自what-is-a-mixin-and-why-are-they-useful这篇回答,就是说当一个功能特性被很多个类用到时,或者一个类需要很多功能特性时
##demo
###werkzeug中Request / Response
答主随后举了werkzeug中Request / Response的例子
If I wanted to make a request object that supports accept headers, etags, authentication, and user agent support, I could do this:
1
2
3
4
|
from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthorizationMixin
class Request(BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthorizationMixin):
pass
|
###django-rest-framework.org/tutorial/3
许多公共行为在REST framework’s mixin类中都实现了.方便的组合与重用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import mixins
from rest_framework import generics
class SnippetList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.MultipleObjectAPIView):
model = Snippet
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
|
MultipleObjectAPIView构建了view, 然后加上了inListModelMixin和CreateModelMixin.
基类提供了核心功能,mixin类提供了 .list() 和 .create() 动作。然后显式的把 get 和 post 方法与合适的动作绑定在一起。
##参考资料