本文由 简悦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类的奥秘。