1.1. Considere o diagrama UML da figura 1 (à direita). Qual das seguintes afirmações está correcta?
1.2. Como se designa a implementação, numa classe, de vários métodos com o mesmo nome, mas com argumentos diferentes?
1.3. Em Java, qual das seguintes frases está incorrecta?
1.4. Em Java, uma interface...
1.5. Em Java, uma excepção...
1.6. Em Java, o método compareTo (definido quando se implementa java.lang.Comparable)...
1.7. Relativamente à interface java.util.Comparator, qual das seguintes frases está correcta?
1.8. Ao utilizar o padrão de desenho Composite passa a ser possível...
1.9. O padrão de desenho Adapter...
1.10. O padrão de desenho Observer...
2.1. (1.5 val.) Descreva em que medida o processo de redefinição de métodos aliado ao mecanismo de herança permite melhorar a escrita de programas.
2.2. (1.5 val.) Os padrões Façade e Bridge permitem abstrair funcionalidade existente através de conceitos que fazem uso dessa funcionalidade. Quais são os objectivos de cada um destes padrões de desenho. Acha que estes padrões de desenho são alternativos, i.e., um deles pode ser usado em alternativa ao outro? Dê um exemplo de utilização, onde se evidenciem as vantagens de cada um deles.
2.3. (1.5 val.) Diga o que entende por polimorfismo e descreva como é explorado no padrão Strategy. Apresente um exemplo de aplicação do padrão.
2.4. (1.0 val.) Considere o padrão de desenho Template Method. 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 interface Predicate {
boolean ok(int value);
}
public class GreaterThan implements Predicate {
private int _value = 0;
public GreaterThan(int value) { _value = value; }
public boolean ok(int value) { return _value < value; }
}
public class EqualTo implements Predicate {
private int _value = 0;
public EqualTo(int value) { _value = value; }
public boolean ok(int value) { return _value == value; }
}
public class DataStore {
int _vector[] = { -1, 0, 1 };
public boolean satisfies(Predicate predicate) {
for (int value : _vector) {
if (predicate.ok(value)) return true;
}
return false;
}
}
public class Application {
public static void main(String args[]) {
DataStore ds = new DataStore();
System.out.println(ds.satisfies(new EqualTo(-1)) ? "YES" : "NO");
//!2.7 – ignorar a linha seguinte na resolução da questão 2.7
System.out.println(ds.satisfies(new GreaterThan(2)) ? "YES" : "NO");
}
}
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 de mobiliário doméstico apostou numa gestão moderna onde os conceitos de estrutura leve e flexível foram aplicados. Assim a empresa não tem, nem meios de produção próprios, nem sistema de distribuição, nem sistema de contabilidade próprios, reduzindo os seus funcionários aos estritamente necessário: departamento de gestão e departamento de vendas. Os departamentos sub-contratados a empresas especializadas têm dois gestores dedicados.
Todo o mobiliário pode ser adquirido individualmente ou, por vezes, em grupos. Por exemplo, a mobília de quarto inclui uma cama, duas mesinhas de cabeceira, uma cómoda e dois tapetes.
Para facilitar a planificação do transporte, cada peça individual é caracterizada com o seu volume e o seu peso, para além do modelo (uma cadeia de caracteres) e do preço. O volume, peso e preço de qualquer grupo é calculado pelo somatório dos seus constituintes (sem qualquer desconto ou agravamento). Deve haver um método que permite calcular estes três atributos.
A empresa é caracterizada pelo seu capital social e pelos seus accionistas. Cada departamento não sub-contratado é caracterizado pelo número de funcionários e todos os departamentos são fornecedores de informação para que o departamento de gestão possa calcular o estado da empresa: saldo contabilístico e saldo financeiro (dep. contabilidade), volume de vendas (dep. vendas), custo de produção de uma peça e tempo para entrega (dep. produção) e número de peças vendidas (dep. distribuiçã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). 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 máquina de lavar tem um mecanismo que gere a abertura da porta, por forma a evitar acidentes com crianças. A máquina tem os seguintes botões e sensores: botão “ligar/desligar” (chama o método power); botão “abrir porta” (método open); sensor “porta fechada” (método closed). A máquina tem ainda um temporizador que emite um impulsos a cada segundo (por cada impulso é chamado o método tick). A máquina apenas pode ser ligada (botão “ligar/desligar”) se a porta estiver fechada: a máquina arranca e apenas pára quando o número de impulsos for igual a 5400 ou quando o botão “ligar/desligar” for premido, interrompendo a lavagem. Quer num caso, quer noutro, a máquina não permite abertura imediata da porta: é necessário esperar 120 impulsos para que a máquina reaja ao botão “abrir porta” (durante o tempo de espera, o botão “ligar/desligar” é ignorado). Caso a porta tenha sido fechada, mas não se tenha iniciado a lavagem, a abertura da porta é imediata. A máquina está inicialmente desligada e a porta está aberta. Represente a abertura da porta através da impressão de uma cadeia de caracteres.
Implemente todas as classes da máquina de lavar com controlador de segurança.
1.1. Considere o diagrama UML da figura 1 (à direita). Qual das seguintes afirmações está correcta?</s>
1.2. Como se designa a implementação, numa classe, de vários métodos com o mesmo nome, mas com argumentos diferentes?
1.3. Em Java, qual das seguintes frases está incorrecta?
1.4. Em Java, uma interface...
1.5. Em Java, uma excepção...
1.6. Em Java, o método compareTo (definido quando se implementa java.lang.Comparable)...
1.7. Relativamente à interface java.util.Comparator, qual das seguintes frases está correcta?
1.8. Ao utilizar o padrão de desenho Composite passa a ser possível...
1.9. O padrão de desenho Adapter...
1.10. O padrão de desenho Observer...
Aspectos importantes:
Aspectos importantes:
Aspectos importantes:
Aspectos importantes:
YES\nNO\n
O padrão utilizado é o Strategy (predicado).
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 State para controlo da porta da máquina.
A máquina é simples: contém as funções a desempenhar e que dependem do estado. Foram omitidos aspectos não importantes para o problema (i.e., como se fecha a porta e como se produzem os impulsos).
public class WashingMachine {
/** Machine state. */
private State _mode = new Open(this);
/** closed sensor */
public void closed() { _mode.closed(); }
/** open button */
public void open() { _mode.open(); }
/** on/off button */
public void power() { _mode.power(); }
/** Timer (one tick per second). */
public void tick() { _mode.tick(); }
/**
* Switch mode. Note that this interface is public.
* @param mode the new mode.
*/
public void setState(State mode) {
_mode = mode;
}
}
A base de definição para os estado é como se indica de seguida. Contém, como se pode inferir da classe anterior, os métodos que dependem do estado da máquina (e que as subclasses de State codificam). Note-se que _machine foi definida como protected para simplificação da apresentação.
public abstract class State {
/** The washing machine. */
protected WashingMachine _machine;
/** @param machine is the washing machine. */
public State(WashingMachine machine) { _machine = machine; }
/** Behaviour for closing. */
public abstract void closed();
/** Behaviour for open. */
public abstract void open();
/** Behaviour for on/off. */
public abstract void power();
/** Behaviour for ticking. */
public abstract void tick();
}
As subclasses definidas para o problema cobrem as seguintes situações: porta aberta (máquina necessariamente desligada); porta fechada (máquina não iniciou lavagem ou espera terminou); máquina a lavar (5400 impulsos ou interrupção via botão on/off); espera depois da lavagem (120 impulsos).
As mensagens são apresentadas apenas por claridade e não são necessárias (excepto onde indicado no enunciado).
Note-se ainda que seria possível factorizar o código de gestão dos impulsos.
public class Open extends State {
/**
* @param machine
*/
public Open(WashingMachine machine) {
super(machine);
System.out.println("** OPEN MODE: reached.");
}
/**
* @see State#closed()
*/
@Override
public void closed() {
System.out.println("** OPEN MODE: closed sensor activated.");
System.out.println("** OPEN MODE: switching to closed/idle mode.");
_machine.setState(new ClosedIdle(_machine));
}
/**
* @see State#open()
*/
@Override
public void open() {
System.out.println("** OPEN MODE: open button pressed (ignored).");
}
/**
* @see Washing#power()
*/
@Override
public void power() {
System.out.println("** OPEN MODE: power button pressed (ignored).");
}
/**
* @see State#tick()
*/
@Override
public void tick() {
System.out.println("** OPEN MODE: tick received (ignored).");
}
}
public class ClosedIdle extends State {
/**
* @param machine
*/
public ClosedIdle(WashingMachine machine) {
super(machine);
System.out.println("** CLOSED/IDLE: reached.");
}
/**
* @see State#closed()
*/
@Override
public void closed() {
System.out.println("** CLOSED/IDLE MODE: closed sensor activated (ignored).");
}
/**
* @see State#open()
*/
@Override
public void open() {
System.out.println("** CLOSED/IDLE MODE: open button pressed.");
System.out.println("** CLOSED/IDLE MODE: switching to open mode.");
_machine.setState(new Open(_machine));
}
/**
* @see Washing#power()
*/
@Override
public void power() {
System.out.println("** CLOSED/IDLE MODE: power (on) button pressed.");
System.out.println("** CLOSED/IDLE MODE: switching to washing mode.");
_machine.setState(new Washing(_machine));
}
/**
* @see State#tick()
*/
@Override
public void tick() {
System.out.println("** CLOSED/IDLE MODE: tick received (ignored).");
}
}
public class Washing extends State {
/**
* Do not stay in this state after ticking this much.
*/
private int MAX_TICKS = 5400;
/**
* How many ticks have we already counted?
*/
private int _ticks = 0;
/**
* @param machine
*/
public Washing(WashingMachine machine) {
super(machine);
System.out.println("** WASHING MODE: reached.");
}
/**
* @see State#closed()
*/
@Override
public void closed() {
System.out.println("** WASHING MODE: closed sensor activated (ignored).");
}
/**
* @see State#open()
*/
@Override
public void open() {
System.out.println("** WASHING MODE: open button pressed (ignored).");
}
/**
* @see State#power()
*/
@Override
public void power() {
System.out.println("** WASHING MODE: power (off) button pressed.");
System.out.println("** WASHING MODE: switching to wait mode.");
_machine.setState(new Wait(_machine));
}
/**
* @see State#tick()
*/
@Override
public void tick() {
System.out.println("** WASHING MODE: tick: " + _ticks);
_ticks++;
if (_ticks >= MAX_TICKS) {
System.out.println("** WASHING MODE: switching to wait mode.");
_machine.setState(new Wait(_machine));
}
}
}
public class Wait extends State {
/**
* Do not stay in this state after ticking this much.
*/
private int MAX_TICKS = 120;
/**
* How many ticks have we already counted?
*/
private int _ticks = 0;
/**
* @param machine
*/
public Wait(WashingMachine machine) {
super(machine);
System.out.println("** WAIT MODE: reached.");
}
/**
* @see State#closed()
*/
@Override
public void closed() {
System.out.println("** WAIT MODE: closed sensor activated (ignored).");
}
/**
* @see State#open()
*/
@Override
public void open() {
System.out.println("** WAIT MODE: open button pressed (ignored).");
}
/**
* @see Wait#power()
*/
@Override
public void power() {
System.out.println("** WAIT MODE: power button pressed (ignored).");
}
/**
* @see State#tick()
*/
@Override
public void tick() {
System.out.println("** WAIT MODE: tick: " + _ticks);
_ticks++;
if (_ticks >= MAX_TICKS) {
System.out.println("** WAIT MODE: switching to idle mode.");
_machine.setState(new ClosedIdle(_machine));
}
}
}