Doesn't change much.
Your Zoo package can have a reanimate method that loads some data from a file or DB. I'll use a flat text file as an example:
Stored Zoo data:
Llama - Feet:4 - Color:Tan
Camel - Feet:4 - Humps:2
The reanimate method will go through this data and do:
#[pseudocode - will not compile]
foreach $line (<FILE>) {
# Get $name and hash data from file
# $name, $animalstats (hashref)
my $newanimal = new Animal($name, $animalstats);
push (@allanimals, $newanimal);
}
This repopulates your zoo with the stored information.
For further enhancement, I'll elaborate on my Animal::Collection idea now.
Your zoo should really contain several collections of animals. This way all animals of a similar type (or habitat) can be grouped together. This makes it easier to count all the animals in a particular type. I would do this with some sort of hashtable containing arrays of animals. (or animal collection objects).
To do this, change the @allanimals array to a hashtable. Key it on the animal type (or habitat, etc).
__DATA__
Llamas:
Llama1 - data data data
Llama2 - data data data
Camels:
Camel1 - data data data
Camel2 - data data data
__CODE__
# [pseudocode]
foreach (my $groupname = from_datafile()) {
## Llamas, Camels, the collections.
unless (exists $allanimals{$groupname})
## Create a new collection if you don't already have one for that
+ animal type.
my $newcollection = new Animal::Collection($groupname);
$allanimals{$groupname} = $newcollection;
}
my $collection = $allanimals{$groupname};
# Now work with that collection. Add all your animals in that group.
foreach $animal (animals_from_datafile()) {
## llama1, llama2, etc.
$collection->add_animal(new Animal($animal,
$animalstats);
}
}
Aside: I'm assuming Animal->new is a factory method.
package Animal;
sub new (
my $name = shift;
my $data = shift;
if($name == 'llama') {
return new Animal::Llama($data);
} elseif ($name == 'camel') {
return new Animal::Camel($data);
} else {
warn "Unknown animal type\n";
return new Animal::Generic($name, $data);
}
}
So, you now have an $allanimals hash that holds all your animals. Each Animal type has it's own subtype, and therefore it's own stats, as per your original requirements.
To work with the animals, you iterate through the collections and animals - use something like:
foreach $type (keys $allanimals) {
my $num_of_animals = $allanimals{$type}->count_collection(); # A met
+hod in Animal::Colelction
foreach $animal ($allanimals{$type}->get_animals()) {
## Using methods defined by the Animal interface
## But implemented in the Animal::Llama, Animal::Camel, etc subcl
+asses.
my $name = $animal->get_name();
$animal->feed();
}
}
The important thing to remember here: A zoo can hold any type of animal. You should never mention a specific animal type in your Zoo object. This makes it very difficult to add new animal types later. There are only 3 places where a specific animal is mentioned: in your datafile, in the subclass, and in the factory method.
~Jon |