The Final Bird Design: The Full Code

The complete, final version of the Bird design from this series, browsable file by file, exactly as it would sit in a real codebase.

September 14, 202618 min read20 / 20

The full evolution walked through every version of this design, one principle at a time. This post is the reference: the final version, as real files in a real folder, in all four languages, compiled and run to make sure every piece actually works together.

The folder layout separates contracts from implementations: every interface (Flyable, Eater, NonFlyable, FlyingBehavior) lives under bird/interfaces/, and every class (Bird and every concrete bird) lives under bird/classes/. The three flying-behavior implementations keep their own flying-behaviors/ subfolder inside classes/, since that trio only ever serves each other.

Java package names can't contain hyphens. While C++, TypeScript, and JavaScript keep that shared flying logic in a bird/classes/flying-behaviors/ folder, Java's copy of that same folder is named bird/classes/flyingbehaviors/. Same code, same reason for existing, just a naming rule Java forces on you that the others don't.
main.cpp
#include <iostream> #include <memory> #include "bird/classes/Bird.h" #include "bird/interfaces/Flyable.h" #include "bird/interfaces/NonFlyable.h" #include "bird/classes/flying-behaviors/CrowOwlFlyingBehavior.h" #include "bird/classes/flying-behaviors/ParrotSparrowFlyingBehavior.h" #include "bird/classes/flying-behaviors/PigeonFlyingBehavior.h" #include "bird/classes/Crow.h" #include "bird/classes/Owl.h" #include "bird/classes/Parrot.h" #include "bird/classes/Sparrow.h" #include "bird/classes/Pigeon.h" #include "bird/classes/Penguin.h" int main() { // Dependency injection: each bird is handed its flying behavior, it never creates one itself. Crow crow("Crow", "black", 2, std::make_unique<CrowOwlFlyingBehavior>()); Owl owl("Owl", "brown", 3, std::make_unique<CrowOwlFlyingBehavior>()); Parrot parrot("Parrot", "green", 1, std::make_unique<ParrotSparrowFlyingBehavior>()); Sparrow sparrow("Sparrow", "brown", 1, std::make_unique<ParrotSparrowFlyingBehavior>()); Pigeon pigeon("Pigeon", "grey", 2, std::make_unique<PigeonFlyingBehavior>()); Penguin penguin("Penguin", "black-and-white", 4); Bird* allBirds[] = { &crow, &owl, &parrot, &sparrow, &pigeon, &penguin }; for (Bird* bird : allBirds) { bird->walk(); } // Flyable* is the single type that means "every bird that can fly", nothing else. Flyable* fliers[] = { &crow, &owl, &parrot, &sparrow, &pigeon }; for (Flyable* bird : fliers) { bird->fly(); } // NonFlyable* is the marker-interface counterpart, only needed because this demo asks for it. NonFlyable* groundedBirds[] = { &penguin }; std::cout << (sizeof(groundedBirds) / sizeof(groundedBirds[0])) << " bird(s) grounded.\n"; crow.eat(); pigeon.eat(); // Swapping Crow to fly like a parrot needs zero changes inside the Crow class itself. Crow crowFlyingLikeAParrot("Crow", "black", 2, std::make_unique<ParrotSparrowFlyingBehavior>()); crowFlyingLikeAParrot.fly(); return 0; }