|
|
(23 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| {{TOCright}}
| | #REDIRECT [[ist:Herança e Composição/Exercício 03: Energia]] |
| = Problema =
| |
| | |
| Considere o [[Introdução aos Objectos/Exercício 02: Energia|Exercício 02]] da [[Introdução aos Objectos]].
| |
| | |
| Resolva agora o mesmo problema, mas considerando as possíveis abstracções de comportamentos e propriedades comuns aos vários conceitos. Defina os conceitos do problema com base nas suas abstracções.
| |
| | |
| Discuta as opções da abstracção, em particular, no que respeita a aspectos menos flexíveis relativamente a possíveis alterações do modelo (constantes, propriedades, comportamentos comuns, etc.). Ainda neste sentido, compare a nova solução com a [[Introdução aos Objectos/Exercício 02: Energia|solução da anterior]]. Chegou à conclusão que a sua nova solução ainda apresenta dificuldades face à manutenção do código? Neste caso, quais são os aspectos problemáticos?
| |
| | |
| = Solução =
| |
| | |
| A solução apresentada procura uma abstracção adequada das propriedades e comportamentos intrínsecos dos conceitos em causa. Alguns aspectos, relativos à abstracção funcional não são ainda considerados.
| |
| | |
| == UML: Diagrama de Classes ==
| |
| | |
| [[Image:PO-dog-cat-mouse-bird-energy-with-inheritance.png]]
| |
| | |
| == Conceito de Animal ==
| |
| | |
| Conceito que gere a energia e o consumo quando se corre, i.e., todos os animais têm energia (boa abstracção) e todos correm (não tão boa, mas neste caso é aceitável, embora haja melhores soluções utilizando técnicas mais avançadas de modelação).
| |
| | |
| <java5>
| |
| public class Animal {
| |
| | |
| /**
| |
| * The animal's base energy value.
| |
| */
| |
| private final int _baseEnergy;
| |
| | |
| /**
| |
| * The dog's current energy value.
| |
| */
| |
| private int _energy;
| |
| | |
| /**
| |
| * The animal's energy spent when running.
| |
| */
| |
| private final int _runEnergy;
| |
| | |
| /**
| |
| * Note that baseEnergy and runEnergy are final and thus, constant after
| |
| * initialization.
| |
| *
| |
| * @param baseEnergy
| |
| * @param energy
| |
| * @param runEnergy
| |
| */
| |
| Animal(int baseEnergy, int energy, int runEnergy) {
| |
| _energy = Math.min(energy, baseEnergy);
| |
| _baseEnergy = baseEnergy;
| |
| _runEnergy = Math.min(runEnergy, baseEnergy);
| |
| }
| |
| | |
| /**
| |
| * @param baseEnergy
| |
| * @param runEnergy
| |
| */
| |
| Animal(int baseEnergy, int runEnergy) {
| |
| _energy = _baseEnergy = baseEnergy;
| |
| _runEnergy = Math.min(runEnergy, baseEnergy);
| |
| }
| |
| | |
| /**
| |
| * @return the animal's base energy level.
| |
| */
| |
| public int getBaseEnergy() {
| |
| return _energy;
| |
| }
| |
| | |
| /**
| |
| * @return the animal's current energy level.
| |
| */
| |
| public int getEnergy() {
| |
| return _energy;
| |
| }
| |
| | |
| /**
| |
| * @param energy
| |
| * the animal's new energy level.
| |
| */
| |
| public void setEnergy(int energy) {
| |
| _energy = energy;
| |
| }
| |
| | |
| /**
| |
| * @return the animal's energy spent when running
| |
| */
| |
| public int getRunEnergy() {
| |
| return _runEnergy;
| |
| }
| |
| | |
| /**
| |
| * @param delta
| |
| */
| |
| void increaseEnergy(int delta) {
| |
| _energy += delta;
| |
| }
| |
| | |
| /**
| |
| * When an animal runs, the energy decreases by 50 units. This value could
| |
| * be defined as an attribute or as a constant.
| |
| *
| |
| * @return whether the dog was able to run.
| |
| */
| |
| public boolean run() {
| |
| if (_energy < _runEnergy)
| |
| return false;
| |
| _energy -= _runEnergy;
| |
| return true;
| |
| }
| |
| | |
| /**
| |
| * Energy is recovered when sleeping.
| |
| */
| |
| public void sleep() {
| |
| _energy = _baseEnergy;
| |
| }
| |
| | |
| /**
| |
| * @see java.lang.Object#equals(java.lang.Object)
| |
| */
| |
| @Override
| |
| public boolean equals(Object o) {
| |
| if (o instanceof Animal) {
| |
| Animal animal = (Animal) o;
| |
| return _baseEnergy == animal.getBaseEnergy() && _energy == animal.getEnergy()
| |
| && _runEnergy == animal.getRunEnergy();
| |
| }
| |
| return false;
| |
| }
| |
| | |
| /**
| |
| * @see java.lang.Object#toString()
| |
| */
| |
| @Override
| |
| public String toString() {
| |
| return "base energy: " + _baseEnergy + ", energy left: " + _energy + ", spent running: "
| |
| + _runEnergy;
| |
| }
| |
| }
| |
| </java5>
| |
| | |
| == Conceito de Animal com Nome ==
| |
| | |
| Tal como no caso anterior, utilizando técnicas de modelação mais avançadas, este conceito poderia não ser sobrecarregado com alguns aspectos, presentes apenas por serem comuns às subclasses (nomeadamente, perseguir e comer ratos).
| |
| | |
| <java5>
| |
| public class NamedAnimal extends Animal {
| |
| | |
| /**
| |
| * The animal's name.
| |
| */
| |
| private String _name;
| |
| | |
| /**
| |
| * Catch rate: success in catching mice.
| |
| */
| |
| private int _catchRate;
| |
|
| |
| /**
| |
| * Note that baseEnergy and runEnergy are final and thus, constant after
| |
| * initialization.
| |
| *
| |
| * @param name
| |
| * @param catchRate
| |
| * @param baseEnergy
| |
| * @param energy
| |
| * @param runEnergy
| |
| */
| |
| NamedAnimal(String name, int catchRate, int baseEnergy, int energy, int runEnergy) {
| |
| super(baseEnergy, energy, runEnergy);
| |
| _name = name;
| |
| _catchRate = catchRate;
| |
| }
| |
| | |
| /**
| |
| * @param name
| |
| * @param catchRate
| |
| * @param baseEnergy
| |
| * @param runEnergy
| |
| */
| |
| NamedAnimal(String name, int catchRate, int baseEnergy, int runEnergy) {
| |
| super(baseEnergy, runEnergy);
| |
| _name = name;
| |
| _catchRate = catchRate;
| |
| }
| |
| | |
| /**
| |
| * @return the animal's name.
| |
| */
| |
| public String getName() {
| |
| return _name;
| |
| }
| |
| | |
| /**
| |
| * Set the animal's name
| |
| *
| |
| * @param name
| |
| * the animal's name
| |
| */
| |
| public void setName(String name) {
| |
| _name = name;
| |
| }
| |
| | |
| /**
| |
| * This is not really a good place for this method, but since only named
| |
| * animals catch mice, we will leave it here for the time being.
| |
| *
| |
| * Call "run" to account for spent energy.
| |
| *
| |
| * @param mouse
| |
| * the mouse to be caught.
| |
| * @return whether the cat was able to catch the mouse. If the mouse
| |
| * escapes, its energy increases.
| |
| */
| |
| public boolean caughtMouse(Mouse mouse) {
| |
| run();
| |
| mouse.run();
| |
| if (0 == (int) (_catchRate * Math.random())) {
| |
| return true;
| |
| }
| |
| mouse.escaped();
| |
| return false;
| |
| }
| |
| | |
| /**
| |
| * This is not really a good place for this method, but since only named
| |
| * animals eat mice, we will leave it here for the time being.
| |
| *
| |
| * Eating is more or less like a vampire feeding...
| |
| *
| |
| * @param mouse
| |
| * the mouse to eat.
| |
| */
| |
| public void eatMouse(Mouse mouse) {
| |
| if (caughtMouse(mouse))
| |
| increaseEnergy(mouse.drain());
| |
| }
| |
| | |
| /**
| |
| * @see java.lang.Object#equals(java.lang.Object)
| |
| */
| |
| @Override
| |
| public boolean equals(Object o) {
| |
| if (o instanceof NamedAnimal) {
| |
| NamedAnimal animal = (NamedAnimal) o;
| |
| return super.equals(o) && _name == animal.getName();
| |
| }
| |
| return false;
| |
| }
| |
| | |
| /**
| |
| * @see java.lang.Object#toString()
| |
| */
| |
| @Override
| |
| public String toString() {
| |
| return _name + ", " + super.toString();
| |
| }
| |
| }
| |
| </java5>
| |
| | |
| == Conceito de Cão ==
| |
| | |
| == Conceito de Gato ==
| |
| | |
| == Conceito de Rato ==
| |
| | |
| == Conceito de Pássaro ==
| |
| | |
| [[category:Ensino]]
| |
| [[category:PO]]
| |