Typescript 之 Mixin (混入)

什么是 Mixin

为对象引入附加的方法或属性,从而达到修改对象结构的目的,即为 mixin.

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    });
}

在Typescipt 之前,很多框架都提供了 Mixin 这个概念,我自己在 Extjs 和 早期的 React 中就学习过混入。

以下代码是 Mixin 在 React 中的使用方法,通过配置,组件可以像调用自己的方法一样调用外部对象的方法。

注: Mixin 在React 16 中已经被废弃了。 废弃的原因在文章的最后会提及。

var myMixin = {
  mixinMethod: function() {
    ...
};

var createReactClass = require('create-react-class');

var TickTock = createReactClass({
  mixins: [myMixin], // 使用 mixin
  
  componentDidMount: function() {
    this.mixinMethod(); // 调用 mixin 上的方法
  },

  render: function() {
    return ...
  }
});

ReactDOM.render(
  <TickTock />,
  document.getElementById('example')
);

Mixin 解决的问题

Mixin 解决的是横切关注点的问题(cross-cutting concern).

横切是 **AOP(Aspect-Oriented Programming,面向切片编程)**中的一个概念。

软件系统,可看作由一组关注点组成。其中,直接的业务关注点,是直切关注点。而为直切关注点提供服务的,就是横切关注点。通常,事务、日志、安全性等关注就是应用中的横切关注功能。

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态横切,即通过重新包装对象,引入对应的 “切面”,即 mixin.

Typescript 中的 mixin

  1. Typescript 中并没有特殊的和 mixin 有关的语法糖
  2. 利用 Typescript 中implements 对类的多继承性来实现 mixin
class Shape {
    draw(): void {
        console.log("shape is drawing");
    }
}

class Component {
    display(): void {
        console.log("component is displaying");
    }
}

class Rectangle implements Shape, Component {
    w: number;
    h: number;

    constructor(w: any, h: any) {
        this.w = w;
        this.h = h;
    }

    area(): number {
        return this.w * this.h;
    }

    //just provide the empty implementation which will be replaced by the mixins helper function
    //same as display: () => void
    display(): void {
    }

    //same as draw: () => void
    draw(): void {
    }
}

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    });
}

applyMixins(Rectangle, [Shape, Component]);

let rectangle: Rectangle = new Rectangle(4, 3);
rectangle.draw();
rectangle.display();
let area = rectangle.area();
console.log(area);

注意:Rectangle 中的空方法签名 draw 和 display 是必须的,如果缺失编译会报错
在这里插入图片描述

mixin 的缺点

大致聊一聊 mixin 的缺点以及为何 React 会放弃它: Mixins Considered Harmful

  1. mixin 导致的隐式依赖 (Mixins introduce implicit dependencies)
    在这里插入图片描述
  2. mixin 导致命名冲突 (Mixins cause name clashes)
  3. mixin 滥用可能会导致代码复杂度直线上升。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值