Mixin介绍

起源: 最近在阅读TensorRT-LLM的源码, 里头有一个比较关键的类GenerationMixin。当时阅读到这里的时候有点奇怪,后缀Mixin表示什么意思?后来在阅读《程序员修炼之道——通向务实的最高境界》一书的继承税一节时,又遇到了Mixin这个关键词。于是做了一番调研,形成本文。
c3yfzI

继承税一节提到三种技术,来尽可能避免继承:

  • 接口与协议
  • 委托
  • mixin与特征

什么是Mixin

mixin的思想很简单: 希望能够为类和对象提供扩展新的功能,但不用继承。 ——《程序员修炼之道》

  • 上面的继承不是指形式上的继承, 而是继承的语义is-a关系。从下面的例子不难发现, mixin实际上使用了继承的形式, 但使用者和mixin不是is-a的关系,而是-able关系。

Mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类。Mixin有时被称作”included”而不是”inherited”。mixin为使用它的class提供额外的功能,但自身却不单独使用(不能单独生成实例对象,属于抽象类)。因为有以上限制,Mixin类通常作为功能模块使用,在需要该功能时“混入”,而且不会使类的关系变得复杂。使用者与Mixin不是“is-a”的关系,而是“-able”关系
Mixin有利于代码复用又避免了多继承的复杂。使用Mixin享有单一继承的单纯性和多重继承的共有性。接口与mixin相同的地方是都可以多继承,不同的地方在于mixin是带实现的。Mixin也可以看作是带实现的interface。这种设计模式实现了依赖反转原则。 ——Wikipedia

  • 多重继承会有diamond dependency problem,举个例子:假如BC继承自AD多重继承自BC,如果BC都override了A中的proc方法,但是D没有override这一方法, 那么D应该使用哪个proc方法呢?
  • 单继承在继承层数较多的情况, 很难确定哪个父类定义了这个方法
  • 使用Minxin,可以避免上述single-inheritance class fragmentationmulitple-inheritance diamond dependency

Python中的Mixin

就以上图为例, GenerationMixin定义了两个函数:

  • get_transformer_layers
  • prepare_basic_inputs

然后每个特定模型的XXXForCausalLM,模型会继承(形式上)两个类, 分别是对应的XXXModelGenerationMixin。单实际上具有继承语义的只是XXXModel, GenerationMixin只是给这个类拓展额外的功能.

C++中的Mixin

拓展阅读1的文章介绍得很详细, 可以直接参考.

拓展阅读

1 通过mixin组合功能
2 Making Python classes more modular using mixins

Comments

Unable to load Disqus, please make sure your network can access.