Created
May 4, 2022 14:32
-
-
Save isaacadariku/0f3fb22a184baf84a41ee9f1c4c521db to your computer and use it in GitHub Desktop.
Keeping your code dry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Let's have two creature classes, | |
// each of them with their own set of behaviours. | |
// The obvious solution would be to directly outline the methods | |
// for each class as we need them ... | |
class Alligator { | |
void swim() => print('Swimming'); | |
void bite() => print('Biting'); | |
void hunt() { | |
print('Alligator -------'); | |
swim(); | |
bite(); | |
print('Eating Lunch'); | |
} | |
} | |
class Crocodile { | |
void swim() => print('Swimming'); | |
void bite() => print('Biting'); | |
void hunt() { | |
print('Crocodile -------'); | |
swim(); | |
bite(); | |
print('Eat Dinner'); | |
} | |
} | |
// If we run our code, our output is | |
void main() { | |
Crocodile().hunt(); | |
Alligator().hunt(); | |
} | |
// Output should be | |
// Crocodile ------- | |
// Swimming | |
// Biting | |
// Eat Dinner | |
// Alligator ------- | |
// Swimming | |
// Biting | |
// Eat Lunch | |
// But classes aren't going to be entirely unique and will share | |
// a lot of commonality with each other. | |
// We obviously want to find the most efficient structure | |
// for writing these classes in the most reusable way. | |
// As you can see, their diet may be different, but the methods | |
// are mostly the same and should ideally be broken out into | |
// something more reusable. | |
// As a mobile developer but familiar with design patterns and | |
// good practice,The most common option we have is extensions | |
// where we can take the properties and methods on one class | |
// and make them available in another, we wiil also need to use | |
// the mixin type to store our methods and use the with keyword | |
// on every class we want it included in. Unlike using only extends, | |
// we can add as many mixins as we want to a class. | |
// This will result to | |
// Create all mixing methods | |
mixin Swim { | |
void swim() => print('Swimming'); | |
} | |
mixin Bite { | |
void bite() => print('Biting'); | |
} | |
// Create an abstract class mixing with various methods | |
abstract class Reptile with Swim, Bite {} | |
// We break Hunt into its own mixin, using the on keyword | |
// to tell it that it will only be used on the Reptile class, | |
// which will give it access to all of its functionality, | |
// like our Swim and Bite mixins. | |
mixin Hunt on Reptile { | |
void hunt(food) { | |
print('${this.runtimeType} -------'); | |
swim(); | |
bite(); | |
print('Eat $food'); | |
} | |
} | |
// Extend the abstract class and with any mixing for the reptile class | |
class Alligator extends Reptile with Hunt { | |
// Alligator Specific stuff... | |
} | |
class Crocodile extends Reptile with Hunt { | |
// Crocodile Specific stuff... | |
} | |
// Now we can now use any other animal freely | |
class Fish with Swim, Bite { | |
void feed() { | |
print('Fish --------'); | |
swim(); | |
bite(); | |
} | |
} | |
// With this we can easuly reuse dart classes and understand the | |
// concept of keep our code DRY | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment