[Dart翻译]Dart中的Mixin介绍

121 阅读2分钟

本文由 简悦SimpRead 转码,原文地址 www.digitalocean.com

学习如何通过使用混搭来保持你的Dart代码的干燥。

使用面向对象编程(OOP)的一些最好的理由是它的技术可以帮助我们保持代码的清洁和干燥。我们将探讨Dart的一些策略,使你的代码可以在独立的类上重复使用。

问题

想象一下,我们有两个生物类,每一个都有自己的一套行为。明显的解决方案是在我们需要的时候直接勾勒出每个类的方法,但是很多类并不是完全独特的,它们之间会有很多共同点。我们显然想找到最有效的结构,以最可重复使用的方式来编写这些类。

我们的动物将有一些它们可以执行的具体动作,以及由这些动作组成的较大的行为。正如你所看到的,它们的饮食可能是不同的,但方法大多是相同的,最好是将其分解成更多的可重复使用的东西。

class Alligator {
  void swim() => print('Swimming');
  void bite() => print('Chomp');
  void crawl() => print('Crawling');
  void hunt() {
    print('Alligator -------');
    swim();
    crawl();
    bite();
    print('Eat Fish');
  }
}

class Crocodile {
  void swim() => print('Swimming');
  void bite() => print('Chomp');
  void crawl() => print('Crawling');
  void hunt() {
    print('Crocodile -------');
    swim();
    crawl();
    bite();
    print('Eat Zebra');
  }
}

main() {
  Crocodile().hunt();
  Alligator().hunt();
}

// Output should be 
// Crocodile -------
// Swimming
// Crawling
// Chomp
// Eat Zebra
// Alligator -------
// Swimming
// Crawling
// Chomp
// Eat Fish

扩展程序

我们最常见的选择是扩展,我们可以把一个类上的属性和方法拿到另一个类中使用。因为我们不会在自己的实例中使用Reptile,所以我们可以把它设置为一个抽象类,所以它不能被初始化,只能被扩展。

abstract class Reptile {
  void bite() => print('Chomp');
  void swim() => print('Swimming');
  void crawl() => print('Crawling');
  void hunt() {
    print('${this.runtimeType} -------');
    swim();
    crawl();
    bite();
  }
}

class Alligator extends Reptile {
    // Alligator Specific stuff...
}

class Crocodile extends Reptile {
    // Crocodile Specific stuff...
}

main() {
  Crocodile().hunt('Zebra');
  Alligator().hunt('Fish');
}

Mixin

这对我们目前的例子来说是很好的,但是当我们添加更多的动物时,很快就会发现这些方法中的很多并不只是针对爬行动物。如果我们想创建一个带有游泳方法的 "鱼 "类,而不是仅仅扩展 "爬行动物",当我们需要从其他类中获得更多的功能时,这样做是非常有限的,因为我们在每个类中只能使用 "扩展"。我们可以使用mixins将我们更普遍的行为分解成更小、更可重用的组件,我们可以将其添加到我们需要的任何类中。

我们只需要使用mixin类型来存储我们的方法,并在每一个我们想要包含的类中使用with关键字。与extends不同的是,我们可以在一个类中添加任意多的mixin。

mixin Swim {
  void swim() => print('Swimming');
}

mixin Bite {
  void bite() => print('Chomp');
}

mixin Crawl {
  void crawl() => print('Crawling');
}

abstract class Reptile with Swim, Crawl, Bite {
  void hunt(food) {
    print('${this.runtimeType} -------');
    swim();
    crawl();
    bite();
    print('Eat $food');
  }
}

class Alligator extends Reptile {
  // Alligator Specific stuff...
}

class Crocodile extends Reptile {
  // Crocodile Specific stuff...
}

class Fish with Swim, Bite {
  void feed() {
    print('Fish --------');
    swim();
    bite();
  }
}

main() {
  Crocodile().hunt('Zebra');
  Alligator().hunt('Fish');
  Fish().feed();
}

On

我们有的最后一个技巧是可以做一些我认为是反向扩展的事情。我们可以创建一个mixin,利用一个类中的方法,然后我们可以在每个子类中使用它。

如果我们想把 "Hunt "分解成自己的混合器,我们可以使用 "on "关键字来告诉它只在 "Reptile "类上使用,这将使它能够使用该类的所有功能,就像我们的 "Swim"、"Crawl "和 "Bite "混合器。

这个配置应该和我们的第一个配置有完全相同的输出。

mixin Hunt on Reptile {
  void hunt(food) {
    print('${this.runtimeType} -------');
    swim();
    crawl();
    bite();
    print('Eat $food');
  }
}

abstract class Reptile with Swim, Crawl, Bite {}

class Alligator extends Reptile with Hunt {
  // Alligator Specific stuff...
}

class Crocodile extends Reptile with Hunt {
  // Crocodile Specific stuff...
}

结论

随着Flutter的日益流行,对Dart编程语言的基础知识有一个很好的了解是个好主意。希望这是个有帮助的介绍,可以澄清一些关于重用Dart类的奥秘。


www.deepl.com 翻译