(New page: {{TOCright}} == Parte 1 (resposta múltipla) == Figura 1 '''1.1.''' Considere o diagrama UML da figura 1 (à direita). Qual das seguintes ...) |
|||
(2 intermediate revisions by the same user not shown) | |||
Line 38: | Line 38: | ||
:#é um tipo primitivo | :#é um tipo primitivo | ||
− | '''1.6.''' Em Java, o parâmetro E em java.util.Iterable | + | '''1.6.''' Em Java, o parâmetro E em java.util.Iterable... |
:#é uma constante que especifica o limite superior para a iteração | :#é uma constante que especifica o limite superior para a iteração | ||
:#é utilizado para definir o passo de iteração (i.e., quantos elementos se deve saltar – por omissão, é 1) | :#é utilizado para definir o passo de iteração (i.e., quantos elementos se deve saltar – por omissão, é 1) | ||
− | :#permite especificar o tipo do comparador de elementos (instância referida por java.util.Comparator | + | :#permite especificar o tipo do comparador de elementos (instância referida por java.util.Comparator) |
:#define tipo retornado pelo iterador correspondente | :#define tipo retornado pelo iterador correspondente | ||
:#não deve ser usado | :#não deve ser usado | ||
Line 77: | Line 77: | ||
'''2.1.''' (1.5 val.) As classes paramétricas permitem uma forma de polimorfismo diferente do que é implicado pelo mecanismo de herança. Quais são as diferenças? Que vantagens estão associadas aos tipos paramétricos? Justifique e dê um exemplo. | '''2.1.''' (1.5 val.) As classes paramétricas permitem uma forma de polimorfismo diferente do que é implicado pelo mecanismo de herança. Quais são as diferenças? Que vantagens estão associadas aos tipos paramétricos? Justifique e dê um exemplo. | ||
− | '''2.2.''' (1.5 val.) O padrão de desenho Visitor permite abstrair funcionalidade a aplicar a uma estrutura de objectos. Quais são as vantagens e inconvenientes associados ao uso deste padrão? Dê um exemplo de utilização, onde se evidenciem as vantagens. Considera que é equivalente ao uso do padrão de desenho Strategy? Justifique. | + | '''2.2.''' (1.5 val.) O padrão de desenho Visitor permite abstrair funcionalidade a aplicar a uma estrutura de objectos. Quais são as vantagens e inconvenientes associados ao uso deste padrão? Dê um exemplo de utilização, onde se evidenciem as vantagens. Considera que é equivalente ao uso do padrão de desenho Strategy? Justifique. |
'''2.3.''' (1.5 val.) Explique quais as vantagens decorrentes do uso do padrão Abstract Factory no desenho de aplicações. Em que medida é importante o polimorfismo nesta situação? Apresente um exemplo que ilustre a sua resposta. | '''2.3.''' (1.5 val.) Explique quais as vantagens decorrentes do uso do padrão Abstract Factory no desenho de aplicações. Em que medida é importante o polimorfismo nesta situação? Apresente um exemplo que ilustre a sua resposta. | ||
Line 84: | Line 84: | ||
'''2.5.1.''' (1.0 val.) Qual o resultado que se obtém quando se executa o programa? (represente mudanças de linha com \n) | '''2.5.1.''' (1.0 val.) Qual o resultado que se obtém quando se executa o programa? (represente mudanças de linha com \n) | ||
− | < | + | <source lang="java"> |
public abstract class Ghost { | public abstract class Ghost { | ||
public Ghost() { System.out.println(getClass().getName()); } | public Ghost() { System.out.println(getClass().getName()); } | ||
Line 120: | Line 120: | ||
} | } | ||
} | } | ||
− | </ | + | </source> |
'''2.5.2.''' (0.5 val.) Que padrão de desenho é usado no programa? | '''2.5.2.''' (0.5 val.) Que padrão de desenho é usado no programa? | ||
Line 182: | Line 182: | ||
:#<s>é um tipo primitivo</s> | :#<s>é um tipo primitivo</s> | ||
− | '''1.6.''' Em Java, o parâmetro E em java.util.Iterable | + | '''1.6.''' Em Java, o parâmetro E em java.util.Iterable... |
:#<s>é uma constante que especifica o limite superior para a iteração</s> | :#<s>é uma constante que especifica o limite superior para a iteração</s> | ||
:#<s>é utilizado para definir o passo de iteração (i.e., quantos elementos se deve saltar – por omissão, é 1)</s> | :#<s>é utilizado para definir o passo de iteração (i.e., quantos elementos se deve saltar – por omissão, é 1)</s> | ||
− | :#<s>permite especificar o tipo do comparador de elementos (instância referida por java.util.Comparator | + | :#<s>permite especificar o tipo do comparador de elementos (instância referida por java.util.Comparator)</s> |
:#define tipo retornado pelo iterador correspondente | :#define tipo retornado pelo iterador correspondente | ||
:#<s>não deve ser usado</s> | :#<s>não deve ser usado</s> | ||
Line 271: | Line 271: | ||
Definem-se quatro conceitos: o beneficiário abstracto (HelpTarget), e cada um dos concretos (Person, Village, Region). | Definem-se quatro conceitos: o beneficiário abstracto (HelpTarget), e cada um dos concretos (Person, Village, Region). | ||
− | < | + | <source lang="java"> |
/** | /** | ||
* Basic help target. | * Basic help target. | ||
Line 284: | Line 284: | ||
public double accept(Calculator calculator) { throw new UnsupportedOperationException(); } | public double accept(Calculator calculator) { throw new UnsupportedOperationException(); } | ||
} | } | ||
− | </ | + | </source> |
− | < | + | <source lang="java"> |
/** | /** | ||
* Individual. | * Individual. | ||
Line 299: | Line 299: | ||
} | } | ||
− | </ | + | </source> |
− | < | + | <source lang="java"> |
import java.util.ArrayList; | import java.util.ArrayList; | ||
Line 339: | Line 339: | ||
public double accept(Calculator calculator) { return calculator.evalVillage(this); } | public double accept(Calculator calculator) { return calculator.evalVillage(this); } | ||
} | } | ||
− | </ | + | </source> |
− | < | + | <source lang="java"> |
import java.util.ArrayList; | import java.util.ArrayList; | ||
Line 379: | Line 379: | ||
public double accept(Calculator calculator) { return calculator.evalRegion(this); } | public double accept(Calculator calculator) { return calculator.evalRegion(this); } | ||
} | } | ||
− | </ | + | </source> |
A classe Calculator define a interface de cálculo para cada conceito. | A classe Calculator define a interface de cálculo para cada conceito. | ||
− | < | + | <source lang="java"> |
/** | /** | ||
* The Calculator visitor interface. | * The Calculator visitor interface. | ||
Line 405: | Line 405: | ||
public abstract double evalRegion(Region region); | public abstract double evalRegion(Region region); | ||
} | } | ||
− | </ | + | </source> |
O processo de cálculo simples é definido pela classe Standard. | O processo de cálculo simples é definido pela classe Standard. | ||
− | < | + | <source lang="java"> |
/** | /** | ||
* "Standard" help calculator. | * "Standard" help calculator. | ||
Line 446: | Line 446: | ||
} | } | ||
− | </ | + | </source> |
O processo de cálculo para emergências é definido pela classe Emergency. | O processo de cálculo para emergências é definido pela classe Emergency. | ||
− | < | + | <source lang="java"> |
/** | /** | ||
* The emergency help system. | * The emergency help system. | ||
Line 497: | Line 497: | ||
} | } | ||
− | </ | + | </source> |
Simple aoolication. | Simple aoolication. | ||
− | < | + | <source lang="java"> |
public class App { | public class App { | ||
/** | /** | ||
Line 522: | Line 522: | ||
} | } | ||
} | } | ||
− | </ | + | </source> |
[[category:PO]] | [[category:PO]] | ||
[[category:Ensino]] | [[category:Ensino]] |
1.1. Considere o diagrama UML da figura 1 (à direita). Qual das seguintes afirmações está correcta?
1.2. Como se designa a operação que permite que um tipo hierarquicamente superior seja usado para referir uma instância de um tipo dele derivado?
1.3. Em Java, qual das seguintes frases está incorrecta?
1.4. Em Java, uma classe anónima...
1.5. Em Java, a classe java.io.Reader...
1.6. Em Java, o parâmetro E em java.util.Iterable...
1.7. Relativamente à interface java.util.Iterator, qual das seguintes frases está correcta?
1.8. O padrão de desenho State...
1.9. O padrão de desenho Template Method...
1.10. O padrão de desenho Observer...
2.1. (1.5 val.) As classes paramétricas permitem uma forma de polimorfismo diferente do que é implicado pelo mecanismo de herança. Quais são as diferenças? Que vantagens estão associadas aos tipos paramétricos? Justifique e dê um exemplo.
2.2. (1.5 val.) O padrão de desenho Visitor permite abstrair funcionalidade a aplicar a uma estrutura de objectos. Quais são as vantagens e inconvenientes associados ao uso deste padrão? Dê um exemplo de utilização, onde se evidenciem as vantagens. Considera que é equivalente ao uso do padrão de desenho Strategy? Justifique.
2.3. (1.5 val.) Explique quais as vantagens decorrentes do uso do padrão Abstract Factory no desenho de aplicações. Em que medida é importante o polimorfismo nesta situação? Apresente um exemplo que ilustre a sua resposta.
2.4. (1.0 val.) Considere o padrão de desenho Composite. Descreva a estrutura prevista pelo padrão, assim como o modo de funcionamento. Quais são as vantagens da sua utilização? Dê um exemplo.
2.5.1. (1.0 val.) Qual o resultado que se obtém quando se executa o programa? (represente mudanças de linha com \n)
public abstract class Ghost {
public Ghost() { System.out.println(getClass().getName()); }
public abstract void tick(Shell shell);
public void tock(Shell shell) {}
}
public class A extends Ghost {
public void tick(Shell shell) { shell.use(new C()); }
}
public class B extends Ghost {
public void tick(Shell shell) { shell.use(new A()); }
public void tock(Shell shell) { shell.use(new A()); }
}
public class C extends Ghost {
public void tick(Shell shell) { shell.use(new B()); }
public void tock(Shell shell) { shell.use(new A()); }
}
public class Shell {
Ghost _ghost = new A();
public void tick() { _ghost.tick(this); }
public void tock() { _ghost.tock(this); }
public void use(Ghost ghost) { _ghost = ghost; }
}
public class GhostInTheShell {
public static void main(String args[]) {
Shell shell = new Shell();
shell.tick();
//!2.7
shell.tick(); shell.tock(); shell.tick();
}
}
2.5.2. (0.5 val.) Que padrão de desenho é usado no programa?
2.6. (2.5 val.) Desenhe o diagrama de classes UML correspondente ao seguinte problema:
Uma empresa especializou-se no fabrico de máquinas de lavar roupa e de máquinas de lavar loiça. A gestão é moderna, sendo as tarefas normalmente executadas pelos gestores (contratar funcionários, por exemplo) e distribuídas por todos os funcionários de forma rotativa. O conselho de gestão tem sempre um operário e um engenheiro.
As máquinas de lavar roupa desta empresa caracterizam-se pela sua segurança, por forma a evitar acidentes com crianças. A máquina de lavar roupa tem os seguintes botões e sensores: botão “ligar/desligar” (evento “press” chama o método “power”); botão “abrir porta” (evento “press” chama método “open”); sensor “porta fechada” (evento “trigger” chama método “closed”). A máquina tem ainda um temporizador, uma cuba rotativa e uma caixa metálica.
As máquinas de lavar loiça são muito semelhantes no hardware, sendo a principal diferença a ausência da cuba rotativa.
A empresa é caracterizada pelo seu capital social, pelo número de máquinas vendidas e pelo número de funcionários. Os funcionários são caracterizados pelo seu vencimento. As máquinas de lavar loiça pelo preço e peso. As máquinas de lavar roupa pelo preço, peso e pelo número de rotações da cuba (centrifugação).
Represente as classes (seus nomes, métodos e atributos). Indique também as relações de herança, associação e agregação.
2.7. (1.5 val.) Desenhe o diagrama de sequência UML correspondente à execução do programa da pergunta 2.5, incluindo as etapas de criação dos objectos (ignore as linhas do programa assinaladas com //!2.7). O diagrama de sequência deve conter os nomes das mensagens trocadas (não é necessário representar os argumentos dessas mensagens nem as de retorno).
2.8. (2.0 val.) Uma agência de apoio humanitário organiza a sua actuação em função dos seus beneficiários: regiões, povoações e indivíduos (uma região contém povoações e as povoações contêm indivíduos). Cada tipo de beneficiário regista o nível de apoio recebido (um valor inteiro). Este valor é utilizado pela agência para determinar quais as regiões, as povoações, ou os indivíduos mais carenciados. A agência sabe que as condições/necessidades de ajuda variam com o período do ano e em função de catástrofes. Como tal, o processo de cálculo e actualização deve ser suficientemente flexível para poder ser alterado conforme as necessidades e deve ser independente dos beneficiários, para evitar introduzir mais complexidade nas suas vidas.
Considerando o exposto acima, a agência define um calculador de benefícios (designado genericamente por Calculator). A implementação mais simples (designada por Standard) contabiliza: para cada indivíduo, uma unidade de ajuda; para cada povoação, o somatório das ajudas aos indivíduos que a habitam; e, para cada região, o somatório dos valores da ajuda dadas às povoações que contém. Existe ainda o calculador para casos de catástrofe (designado por Emergency), que difere do Standard por contabilizar menos ajuda (apenas 75% do total) para povoações com mais de 100 indivíduos e menos ajuda (apenas 90% do total) para regiões com mais de 20 povoações.
Implemente todos os conceitos. Considere que deve ser possível definir novas formas de cálculo sem necessitar alterar, nem os indivíduos, nem as povoações, nem as regiões.
1.1. Considere o diagrama UML da figura 1 (à direita). Qual das seguintes afirmações está correcta?
1.2. Como se designa a operação que permite que um tipo hierarquicamente superior seja usado para referir uma instância de um tipo dele derivado?
1.3. Em Java, qual das seguintes frases está incorrecta?
1.4. Em Java, uma classe anónima...
1.5. Em Java, a classe java.io.Reader...
1.6. Em Java, o parâmetro E em java.util.Iterable...
1.7. Relativamente à interface java.util.Iterator, qual das seguintes frases está correcta?
1.8. O padrão de desenho State...
1.9. O padrão de desenho Template Method...
1.10. O padrão de desenho Observer...
Aspectos importantes:
Aspectos importantes:
Aspectos importantes:
Aspectos importantes:
A\nC\nB\nA\nC\n
O padrão utilizado é o State (Ghost).
Esboço do diagrama de classes para o problema apresentado.
Note-se que alguns objectos não indicam variáveis associadas (os resultados da criação desses objectos são imediatamente passados como argumentos de outros métodos).
Usa-se o padrão Visitor como forma de abstrair o cálculo da ajuda prestada.
Definem-se quatro conceitos: o beneficiário abstracto (HelpTarget), e cada um dos concretos (Person, Village, Region).
/**
* Basic help target.
*/
public abstract class HelpTarget {
/**
* No actual value is returned in this case.
*
* @param calculator the visitor used to evaluate assistance.
* @return help received by this target.
*/
public double accept(Calculator calculator) { throw new UnsupportedOperationException(); }
}
/**
* Individual.
* We omitted the initialisation code.
*/
public class Person extends HelpTarget {
/**
* @see HelpTarget#accept(Calculator)
*/
@Override
public double accept(Calculator calculator) { return calculator.evalPerson(this); }
}
import java.util.ArrayList;
/**
* A village has villagers (persons).
* We omitted the initialisation code.
*/
public class Village extends HelpTarget {
/**
* The villagers in this village.
*/
private ArrayList<Person> _villagers = new ArrayList<Person>();
/**
* Simple constructor for initialising the village with some villagers.
*/
public Village() {
int count = (int) (Math.random() * 100);
for (int i = 0; i < count; i++) _villagers.add(new Person());
}
/**
* @return size of village (number of villagers).
*/
public int size() { return _villagers.size(); }
/**
* @param index
* @return a villager
*/
public Person getVillager(int index) { return _villagers.get(index); }
/**
* @see HelpTarget#accept(Calculator)
*/
@Override
public double accept(Calculator calculator) { return calculator.evalVillage(this); }
}
import java.util.ArrayList;
/**
* A region has villages.
* We omitted the initialisation code.
*/
public class Region extends HelpTarget {
/**
* The villages in this region.
*/
private ArrayList<Village> _villages = new ArrayList<Village>();
/**
* Simple constructor for initialising the region with some villages.
*/
public Region() {
int count = (int) (Math.random() * 100);
for (int i = 0; i < count; i++) _villages.add(new Village());
}
/**
* @return size of region (number of villages).
*/
public int size() {return _villages.size(); }
/**
* @param index
* @return a village
*/
public Village getVillage(int index) { return _villages.get(index); }
/**
* @see HelpTarget#accept(Calculator)
*/
@Override
public double accept(Calculator calculator) { return calculator.evalRegion(this); }
}
A classe Calculator define a interface de cálculo para cada conceito.
/**
* The Calculator visitor interface.
*/
public abstract class Calculator {
/**
* @param person
* @return help received by this person.
*/
public abstract double evalPerson(Person person);
/**
* @param village
* @return help received by this village.
*/
public abstract double evalVillage(Village village);
/**
* @param region
* @return help received by this region.
*/
public abstract double evalRegion(Region region);
}
O processo de cálculo simples é definido pela classe Standard.
/**
* "Standard" help calculator.
*/
public class Standard extends Calculator {
/**
* @see Calculator#evalVillage(Village)
*/
@Override
public double evalVillage(Village village) {
double tax = 0;
for (int index = 0; index < village.size(); index++)
tax += village.getVillager(index).accept(this);
return tax;
}
/**
* @see Calculator#evalPerson(Person)
*/
@Override
public double evalPerson(Person person) {
return 1;
}
/**
* @see Calculator#evalRegion(Region)
*/
@Override
public double evalRegion(Region region) {
double tax = 0;
for (int index = 0; index < region.size(); index++)
tax += region.getVillage(index).accept(this);
return tax;
}
}
O processo de cálculo para emergências é definido pela classe Emergency.
/**
* The emergency help system.
*/
public class Emergency extends Calculator {
/**
* High-water marker for region occupation.
*/
private final int REGION_MAX = 20;
/**
* High-water marker for population.
*/
private final int VILLAGE_MAX = 100;
/**
* @see Calculator#evalVillage(Village)
*/
@Override
public double evalVillage(Village village) {
double help = 0;
for (int index = 0; index < village.size(); index++)
help += village.getVillager(index).accept(this);
if (village.size() > VILLAGE_MAX) help *= .75;
return help;
}
/**
* @see Calculator#evalPerson(Person)
*/
@Override
public double evalPerson(Person person) { return 1; }
/**
* @see Calculator#evalRegion(Region)
*/
@Override
public double evalRegion(Region region) {
double help = 0;
for (int index = 0; index < region.size(); index++)
help += region.getVillage(index).accept(this);
if (region.size() > REGION_MAX) help *= .9;
return help;
}
}
Simple aoolication.
public class App {
/**
* @param args
*/
public static void main(String[] args) {
HelpTarget v1 = new Village();
HelpTarget r1 = new Region();
HelpTarget p1 = new Person();
Calculator sh = new Standard();
Calculator eh = new Emergency();
System.out.println("Village help (standard): " + v1.accept(sh));
System.out.println("Region taxes (standard): " + r1.accept(sh));
System.out.println("Person taxes (standard): " + p1.accept(sh));
System.out.println("Village taxes (emergency): " + v1.accept(eh));
System.out.println("Region taxes (emergency): " + r1.accept(eh));
System.out.println("Person taxes (emergency): " + p1.accept(eh));
}
}