Skip to content

Instantly share code, notes, and snippets.

@andhieka
Last active May 14, 2020 07:58
Show Gist options
  • Save andhieka/5cbc9317158188e827d8a1fbd97ad7ae to your computer and use it in GitHub Desktop.
Save andhieka/5cbc9317158188e827d8a1fbd97ad7ae to your computer and use it in GitHub Desktop.
Visitor Pattern - Dart (After)
//#region Zoo
enum VisitOrder {
age,
name,
species,
}
class Zoo {
final List<Dog> dogs;
final List<Cat> cats;
final List<Bear> bears;
const Zoo({
this.dogs,
this.cats,
this.bears,
});
int get totalAnimalInZoo => dogs.length + cats.length + bears.length;
Iterator<Animal> makeIteratorBySpecies() {
List<Animal> animals = [];
animals.addAll(bears);
animals.addAll(cats);
animals.addAll(dogs);
return animals.iterator;
}
Iterator<Animal> makeIteratorByName() {
List<Animal> animals = [];
animals.addAll(bears);
animals.addAll(cats);
animals.addAll(dogs);
animals.sort((firstAnimal, secondAnimal) {
return secondAnimal.name.compareTo(firstAnimal.name);
});
return animals.iterator;
}
Iterator<Animal> makeIteratorByAge() {
List<Animal> animals = [];
animals.addAll(bears);
animals.addAll(cats);
animals.addAll(dogs);
animals.sort((firstAnimal, secondAnimal) {
return secondAnimal.birthday.compareTo(firstAnimal.birthday);
});
return animals.iterator;
}
Iterator<Animal> makeIterator(VisitOrder visitOrder) {
switch (visitOrder) {
case VisitOrder.age:
return makeIteratorByAge();
case VisitOrder.name:
return makeIteratorByName();
case VisitOrder.species:
return makeIteratorBySpecies();
}
}
void accept(Visitor visitor, VisitOrder visitOrder) {
final iterator = makeIterator(visitOrder);
while (iterator.moveNext()) {
iterator.current.accept(visitor);
}
}
}
//#endregion
//#region Composite
abstract class Animal {
String get name;
int get weight;
DateTime get birthday;
void accept(Visitor visitor);
}
class Cat implements Animal {
final String name;
final int weight;
final DateTime birthday;
const Cat({this.name, this.weight, this.birthday});
void accept(Visitor visitor) {
visitor.visitCat(this);
}
}
class Dog implements Animal {
final String name;
final int weight;
final DateTime birthday;
const Dog({this.name, this.weight, this.birthday});
void accept(Visitor visitor) {
visitor.visitDog(this);
}
}
class Bear implements Animal {
final String name;
final int weight;
final DateTime birthday;
const Bear({this.name, this.weight, this.birthday});
void accept(Visitor visitor) {
visitor.visitBear(this);
}
}
//#endregion
//#region Visitor
abstract class Visitor {
void visitCat(Cat cat);
void visitDog(Dog dog);
void visitBear(Bear bear);
}
class HealthCheckVisitor implements Visitor {
void visitCat(Cat cat) {
if (cat.weight < 2) {
print(" Cat ${cat.name} is underweight.");
} else if (cat.weight < 10) {
print(" Cat ${cat.name} is healthy.");
} else {
print(" Cat ${cat.name} is obese.");
}
}
void visitDog(Dog dog) {
if (dog.weight < 2) {
print(" Dog ${dog.name} is underweight.");
} else if (dog.weight < 10) {
print(" Dog ${dog.name} is healthy.");
} else {
print(" Dog ${dog.name} is obese.");
}
}
void visitBear(Bear bear) {
if (bear.weight < 20) {
print(" Bear ${bear.name} is underweight.");
} else if (bear.weight < 100) {
print(" Bear ${bear.name} is healthy.");
} else {
print(" Bear ${bear.name} is obese.");
}
}
}
class HappyBirthdayVisitor implements Visitor {
void checkBirthday(Animal animal) {
if (animal.birthday.day == DateTime.now().day &&
animal.birthday.month == DateTime.now().month) {
print("");
print(" Happy birthday ${animal.name}...");
print(" Happy birthday ${animal.name}...");
print(" Happy birthday dear ${animal.name}...");
print(" Happy birthday to you...");
print("");
} else {
print(" It's not ${animal.name}'s birthday");
}
}
void visitCat(Cat cat) {
checkBirthday(cat);
}
void visitDog(Dog dog) {
checkBirthday(dog);
}
void visitBear(Bear bear) {
checkBirthday(bear);
}
}
class MealDispenserVisitor implements Visitor {
void visitCat(Cat cat) {
print(" Feeding fish to ${cat.name}");
}
void visitDog(Dog dog) {
print(" Feeding meat to ${dog.name}");
}
void visitBear(Bear bear) {
print(" Feeding honey to ${bear.name}");
}
}
//#endregion
void main() {
Zoo zoo = Zoo(
cats: [
Cat(name: "Kibum", weight: 15, birthday: DateTime(2005, 1, 15)),
],
dogs: [
Dog(name: "Apple", weight: 5, birthday: DateTime(2019, 11, 11)),
Dog(name: "Dalmatian", weight: 12, birthday: DateTime(1995, 5, 4)),
],
bears: [
Bear(name: "Teddy", weight: 10, birthday: DateTime(2018, 1, 30)),
Bear(name: "Lotso", weight: 75, birthday: DateTime(1992, 5, 14)),
],
);
print("Performing health check");
print("-----------------------");
final healthCheckVisitor = HealthCheckVisitor();
zoo.accept(healthCheckVisitor, VisitOrder.name);
print("");
print("Performing birthday check");
print("-----------------------");
final happyBirthdayVisitor = HappyBirthdayVisitor();
zoo.accept(happyBirthdayVisitor, VisitOrder.name);
print("");
print("Performing daily feeding");
print("-----------------------");
final mealDispenserVisitor = MealDispenserVisitor();
zoo.accept(mealDispenserVisitor, VisitOrder.age);
print("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment