zoukankan      html  css  js  c++  java
  • 【JS】602- Mixin!这是做什么的,如何使用?

    本文转载于 SegmentFault 社区

    作者:小红星闪啊闪

    这里补充一下Mixin的定义:


    只要一个类是继承自Object的而且没有定义构造方法,那么这个类可以是一个Mixin了。当然,如果你想让mixin的定义更加的清晰,可以使用mixin关键字开头来定义。具体请参考这里

    原文截图体会一下风格。



    正文

    在经典的面向对象编程语言里一定会有常规的类,抽象类和接口。当然,Dart也有它自己的接口,不过那是另外的文章要说的。有的时候阴影里潜伏者另外的野兽:Mixin!这是做什么的,如何使用?我们来一起发现。




    没有mixin的世界

    假设你在构建一个模拟野生动物的app,那么你需要一个Mosquito(蚊子)类。作为一个有预见性的开发人员,你会抽象蚊子们有的共通的东西然后放在一个抽象类里。

    abstract class Insect {  void crawl() {    print('crawling');  }}
    abstract class AirborneInsect extends Insect {  void flutter() {    print('fluttering');  }
      void buzz() {    print('buzzing annoyingly')  }}
    class Mosquito extends AirborneInsect {  void doMosquitoThing() {    crawl();    flutter();    buzz();    print('sucking blood');  }}
    

    很棒!你已经做到了!添加新的昆虫就如同微风拂过一样,根本不会有代码的冗余出现。。。一直到你发现你需要一个Swallow类(就是一种可以吃掉整个蚊子的东西)

    同样的也有很多鸟类共有的东西,我们可以创建一个Bird类。这个时候问题就出现了 -- 鸟也会振动翅膀!但是,你没法把flutter方法从AirboneInsect类里面提取出来组成一个新的类Fluttering。

    为什么?Bird类可以继承Fluttering类,但是AirboneInsect不可以,它已经继承了Insect类了。Dart可不支持多继承(真很好)

    这下,你需要给Bird类添加一个flutter方法了。代码冗余发生了!

    abstract class Bird {  void chirp() {    print('chirp chirp');  }
      // Duplicate method  void flutter() {    print('fluttering');  }}
    class Swallow extends Bird {  void doSwallowThing() {    chirp();    flutter();    print('eating a mosquito');  }}
    

    使用mixin

    Mixin的定义是“一种把类代码用在多个继承树的方法”。简单的说,mixin让你不用继承就可以引入代码块的方法。声明一个mixin非常的简单:

    mixin Fluttering {    void flutter() {        pring('fluttering');    }}
    

    这个mixin可以用在常规的类上面也可以用在抽象类,只需要一个with关键字。在野生动物模拟app例子里,你也许要用在抽象类上了。

    mixin Fluttering {  void flutter() {    print('fluttering');  }}
    abstract class Insect {  void crawl() {    print('crawling');  }}
    abstract class AirborneInsect extends Insect with Fluttering {  void buzz() {    print('buzzing annoyingly');  }}
    class Mosquito extends AirborneInsect {  void doMosquitoThing() {    crawl();    flutter();    buzz();    print('sucking blood');  }}
    abstract class Bird with Fluttering {  void chirp() {    print('chirp chirp');  }}
    class Swallow extends Bird {  void doSwallowThing() {    chirp();    flutter();    print('eating a mosquito');  }}
    

    也可以在一个类上面使用多个mixin。如果需要在Bird类上用一个chirping mixn的话,就和Fluttering mixin一起用就好。

    abstract class Bird with Fluttering, Chirping
    

    限制Mixin的使用

    有的时候你不想让mixin用在早已存在的类上面,你只是想让它用在某些特定的类或者其子类上。这通常你的代码对早已存在的代码有依赖。

    在野生动物app这个例子里,你发现仅仅支持swallow已经不够了。还有其他种类的鸟比如麻雀或者Blue Jay等。与麻雀不同,很多其他的鸟需要从地里面啄食,种子啊,虫子啊的。。。

    给Bird抽象类添加方法是不可能的,因为不是所有的鸟都需要啄食。所以,为了避免代码冗余,你可以创建一个叫做Pecking的mixin。

    mixin Pecking {
      void peck() {
        print('pecking');
      }
    }
    

    这至少比代码荣誉好很多了。但是,也会有人把这个mixin用在Insect类上。这样使用mixin问题就大了。

    当你开始研究一个鸟类的动作的时候,你会发现鸟儿在逐出食物之后就会发出愉悦的鸟鸣。从当前的mixin里面调用chirp方法是不可能的。要改也非常简单,只要告诉Dart,Pecking mixin只能用在Bird类上面。现在调用Bird类的方法就没有问题了。

    //...mixin Pecking on Bird {    void peck() {        print('pecking');        chirp();    }}
    class Sparrow extends Bird with Pecking {}
    class BlueJay extends Bird with Pecking {}
    

    结论

    Mixin对于继承体系中避免代码的冗余非常有用处。mixin也可以被约束在只可以用在某些特定的类上面,这让他们成为了开发的一大利器!

    参考链接:

    https://resocoder.com/2019/07/21/mixins-in-dart-understand-dart-flutter-fundamentals-tutorial/

    原创系列推荐

    1. JavaScript 重温系列(22篇全)

    2. ECMAScript 重温系列(10篇全)

    3. JavaScript设计模式 重温系列(9篇全)

    4. 正则 / 框架 / 算法等 重温系列(16篇全)

    5. Webpack4 入门(上)|| Webpack4 入门(下)

    6. MobX 入门(上) ||  MobX 入门(下)

    7. 59篇原创系列汇总

    回复“加群”与大佬们一起交流学习~

    点这,与大家一起分享本文吧~

  • 相关阅读:
    Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name
    docker-compose 安装solr+ikanalyzer
    centos 安装Python3
    spring+springmvc+mybatis 开发JAVA单体应用
    职责链模式例子
    ssm(spring、springmvc、mybatis)框架整合
    PAT (Advanced Level) Practise
    PAT (Advanced Level) Practise
    PAT (Advanced Level) Practise
    PAT (Advanced Level) Practise
  • 原文地址:https://www.cnblogs.com/pingan8787/p/13069355.html
Copyright © 2011-2022 走看看