Programação com Objectos/Teste de 2009/01/24

From Wiki**3

< Programação com Objectos

Parte 1 (resposta múltipla)

Figura 1

1.1. Considere o diagrama UML (Figura 1, à direita). Qual das seguintes afirmações está correcta?

  1. é sempre possível fazer casts de referências do tipo A para as do tipo I
  2. doThat está acessível através do tipo I
  3. doIt só pode ser invocado a partir de referências do tipo B
  4. A implementação de doThis da interface I está em A
  5. B é uma classe derivada de I

1.2. A definição de métodos, por uma classe, de métodos especificados numa interface, designa-se por:

  1. encapsulamento
  2. implementação
  3. downcasting
  4. abstracção
  5. sobrecarregar (overloading)

1.3. Em Java, qual das seguintes frases está correcta?

  1. todas as classes herdam da classe Class
  2. uma classe interna não pode ser qualificada static
  3. uma excepção não pode ser lançada num método que não a declare
  4. uma classe interna pode ser definida como implementação anónima de uma interface
  5. é obrigatório definir pelo menos um método abstracto dentro de uma classe classe abstracta

1.4. A definição de uma classe por agregação de objectos de outras classes ou suas colecções designa-se por:

  1. upcasting
  2. abstracção
  3. composição
  4. herança
  5. extensão

1.5. Em Java, a operação de serialização...

  1. está automaticamente disponível para todas as classes
  2. não está disponível para classes que derivem de classes fora da sua package
  3. permite recuperar objectos em execuções futuras de uma aplicação
  4. requer a definição de métodos específicos na classe dos objectos a serializar
  5. não pode ser aplicada a estruturas de objectos

1.6. Em Java, relativamente à redefinição de métodos...

  1. pode ser feita em qualquer subclasse
  2. pode ser realizada para todos os métodos
  3. pode ser realizada para métodos protected
  4. pode realizar-se apenas entre classes da mesma package
  5. se as classes pertencerem a packages diferentes, é necessário implementar a interface Externalizable

1.7. Em Java, uma classe anónima...

  1. é um tipo primitivo
  2. pode ser definida no corpo de um método
  3. não pode implementar o método toString
  4. não pode ser uma classe interna
  5. as respostas anteriores estão erradas

1.8. A utilização do padrão de desenho Façade...

  1. permite mudar o comportamento de um objecto quando o seu estado muda
  2. permite adicionar responsabilidades a objectos individuais em tempo de execução
  3. permite representar uma operação a ser realizada sobre os elementos de uma estrutura de objectos
  4. não é compatível com o uso de classes abstractas
  5. permite utilizar uma interface simplificada para um conjunto de classes

1.9. O padrão de desenho Visitor...

  1. permite gerir as dependências de outros objectos relativamente ao estado de um objecto
  2. não pode ser aplicado em conjunto com padrão State
  3. permite adicionar funcionalidade a um objecto, mas altera a sua interface
  4. permite aplicar uma operação a uma estrutura de objectos
  5. permite estabelecer o esqueleto de um algoritmo

1.10. O padrão de desenho Abstract Factory...

  1. permite adicionar funcionalidade a um objecto sem alterar a sua interface
  2. permite aplicar uma operação a uma estrutura de objectos
  3. permite abstrair a criação de famílias de objectos para uma aplicação
  4. permite tratar famílias de objectos e seus grupos indiscriminadamente
  5. permite gerir as dependências de outros objectos relativamente ao estado de um objecto

Parte 2

2.1. (1.5 val.) As classes internas em Java apresentam características que as tornam num mecanismo interessante para realizar de forma simples tarefas cujo encapsulamento poderia revelar-se complexo. Descreva as características de uma classe interna em Java e descreva um exemplo onde sejam evidenciadas vantagens da sua utilização.

2.2. (1.0 val.) Os padrões de desenho State e Strategy apresentam várias características comuns, tanto na estrutura, como na execução das operações. Acha que são intercambiáveis, ou que, pelo contrário, os casos de uso são diferentes? Justifique.

2.3. (1.5 val.) O conceito abstracto de interface representa um mecanismo poderoso na programação modular em geral e na programação por objectos em particular. Explique (por palavras suas) em que consistem as vantagens do desenvolvimento baseado em interfaces e que formas o Java tem de o disponibilizar.

2.4. (1.5 val.) Considere o seguinte problema. Um editor gráfico realiza manipulações sobre as entidades que aparecem na área de desenho (imagens, polígonos, caixas de texto, etc.). É desejável que cada operação possa ser reproduzida ou invertida, tendo, para tal, de ser guardada. Que padrão de desenho pode ser usado? Explique como o usaria.

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) <java5> import java.util.ArrayList; abstract class Printable {

 public abstract String show();
 public void add(Printable p) { throw new UnsupportedOperationException(); }

}

class Paragraph extends Printable {

 public String show() { return "[paragraph]"; }

}

class Image extends Printable {

 public String show() { return "[image]"; }

}

class Album extends Printable {

 public ArrayList<Printable> _printables = new ArrayList<Printable>();
 public void add(Printable p) { _printables.add(p); }
 public String show() {
   String s = "[";
   for (Printable p: _printables) s += p.show();
   s += "]";
   return s;
 }

}

class Page extends Album {} class Book extends Album {}

public class App {

 public static void main(String args[]) {
   Page page1 = new Page();
   page1.add(new Paragraph());
   page1.add(new Image());
   Page page2 = new Page();              //!2.7
   page2.add(new Paragraph());           //!2.7
   page2.add(new Image());               //!2.7
   Book book = new Book();
   book.add(page1);
   book.add(page2);                      //!2.7
   System.out.println(book.show());
 }

} </java5>

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:

Um empreiteiro da construção civil especializou-se na construção de vivendas e piscinas. Devido ao modo de construção modular, o negócio está a correr muito bem: existem muitas encomendas e os funcionários conseguem satisfazê-las a todas fazendo horas extraordinárias. Os operários (montam as vivendas e as piscinas) andam muito satisfeitos pois o vencimento mensal é função da antiguidade, do ordenado de base e das horas extraordinárias efectuadas. Os coordenadores de operários não recebem horas extraordinárias, mas recebem um prémio por cada vivenda ou piscina concluída. Os empregados do “backoffice” não recebem horas extraordinárias nem qualquer prémio.

As vivendas são construídas com base em módulos pré-fabricados: casas de banho, cozinhas, quartos, escadas e elevadores. Para equipar estas divisões, a empresa adquire sanitas, banheiras, lavatórios (usados nas casas de banho e nas cozinhas), candeeiros e interruptores.

Represente as classes pelos 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 (excepto as linhas marcadas com //!2.7), incluindo as etapas de criação dos objectos. O diagrama de sequência deve conter os nomes das mensagens trocadas (não é necessário representar os argumentos dessas mensagens nem as correspondentes ao retorno).

2.8. (2.0 val.) Considere o seguinte problema. Uma loja mantém registos persistentes sobre os seus clientes: número de cliente, nome, contacto, data de nascimento e data da primeira compra. Mantém também um registo de cada compra que o cliente realizou ao longo tempo: data da compra, valor da compra, tipo de produto adquirido e modo de pagamento (dinheiro, cartão de débito, cartão de crédito bancário ou cartão de compras da loja). A loja dá prémios de fidelidade aos seus clientes, sob a forma de descontos. No final de cada ano, a loja precisa de produzir relatórios em função dos clientes. Assim, deve ser possível obter, com relativamente pouco esforço, diversas listas de clientes com base em critérios julgados interessantes (segmento etário, segmento por compras acumuladas, etc.). Concretize este problema em Java, definindo as classes que achar necessárias.

2.9. (2.0 val.) Altere (o menos possível) o programa abaixo para que seja mais simples adicionar formas de apresentação específicas a cada elemento de uma página. A nova implementação deve suportar novas adições de formas de apresentação com menos impacto que a apresentada: em particular, deveria ser possível acrescentar novas formas de apresentação sem alterar o código que obtiver. <java5> import java.util.ArrayList; abstract class Printable {

 public abstract String show();
 public void add(Printable p) { throw new UnsupportedOperationException(); }

}

class Paragraph extends Printable {

 public String show() { return "[paragraph]"; }

}

class Image extends Printable {

 public String show() { return "[image]"; }

}

class Album extends Printable {

 public ArrayList<Printable> _printables = new ArrayList<Printable>();
 public void add(Printable p) { _printables.add(p); }
 public String show() {
   String s = "[";
   for (Printable p: _printables) s += p.show();
   s += "]";
   return s;
 }

}

class Page extends Album {} class Book extends Album {} </java5>

Chave da Parte 1

Figura 1

1.1. Considere o diagrama UML (Figura 1, à direita). Qual das seguintes afirmações está correcta?

  1. é sempre possível fazer casts de referências do tipo A para as do tipo I
  2. doThat está acessível através do tipo I
  3. doIt só pode ser invocado a partir de referências do tipo B
  4. A implementação de doThis da interface I está em A
  5. B é uma classe derivada de I

1.2. A definição de métodos, por uma classe, de métodos especificados numa interface, designa-se por:

  1. encapsulamento
  2. implementação
  3. downcasting
  4. abstracção
  5. sobrecarregar (overloading)

1.3. Em Java, qual das seguintes frases está correcta?

  1. todas as classes herdam da classe Class
  2. uma classe interna não pode ser qualificada static
  3. uma excepção não pode ser lançada num método que não a declare
  4. uma classe interna pode ser definida como implementação anónima de uma interface
  5. é obrigatório definir pelo menos um método abstracto dentro de uma classe classe abstracta

1.4. A definição de uma classe por agregação de objectos de outras classes ou suas colecções designa-se por:

  1. upcasting
  2. abstracção
  3. composição
  4. herança
  5. extensão

1.5. Em Java, a operação de serialização...

  1. está automaticamente disponível para todas as classes
  2. não está disponível para classes que derivem de classes fora da sua package
  3. permite recuperar objectos em execuções futuras de uma aplicação
  4. requer a definição de métodos específicos na classe dos objectos a serializar
  5. não pode ser aplicada a estruturas de objectos

1.6. Em Java, relativamente à redefinição de métodos...

  1. pode ser feita em qualquer subclasse
  2. pode ser realizada para todos os métodos
  3. pode ser realizada para métodos protected
  4. pode realizar-se apenas entre classes da mesma package
  5. se as classes pertencerem a packages diferentes, é necessário implementar a interface Externalizable

1.7. Em Java, uma classe anónima...

  1. é um tipo primitivo
  2. pode ser definida no corpo de um método
  3. não pode implementar o método toString
  4. não pode ser uma classe interna
  5. as respostas anteriores estão erradas

1.8. A utilização do padrão de desenho Façade...

  1. permite mudar o comportamento de um objecto quando o seu estado muda
  2. permite adicionar responsabilidades a objectos individuais em tempo de execução
  3. permite representar uma operação a ser realizada sobre os elementos de uma estrutura de objectos
  4. não é compatível com o uso de classes abstractas
  5. permite utilizar uma interface simplificada para um conjunto de classes

1.9. O padrão de desenho Visitor...

  1. permite gerir as dependências de outros objectos relativamente ao estado de um objecto
  2. não pode ser aplicado em conjunto com padrão State
  3. permite adicionar funcionalidade a um objecto, mas altera a sua interface
  4. permite aplicar uma operação a uma estrutura de objectos
  5. permite estabelecer o esqueleto de um algoritmo

1.10. O padrão de desenho Abstract Factory...

  1. permite adicionar funcionalidade a um objecto sem alterar a sua interface
  2. permite aplicar uma operação a uma estrutura de objectos
  3. permite abstrair a criação de famílias de objectos para uma aplicação
  4. permite tratar famílias de objectos e seus grupos indiscriminadamente
  5. permite gerir as dependências de outros objectos relativamente ao estado de um objecto

Resolução da Parte 2

2.1. Classes Internas

Aspectos importantes:

  • acesso privilegiado à classe contentora;
  • encapsulamento da classe interna pela contentora (eventualmente protegido);
  • implementação de interfaces externas por código protegido.

Exemplos:

  • comparadores de Strings Java;
  • Gato e Estômago (em que o estômago é implementado pelo gato, mas obedecendo a interface exterior);
  • iteradores e colecções em Java.

2.2. State & Strategy

2.3. Interfaces

2.4. Operações com redo/undo

Padrão comando: encapsulamento de operações como objectos.

Métodos a implementar nos comandos:

  • do/redo e
  • undo.

2.5.1. Saída do programa

 [[[paragraph][image]][[paragraph][image]]]

2.5.2. Identificação do padrão de desenho utilizado

O padrão utilizado é o Composite (elementos "Printable").

2.6. Diagrama de classes (UML)

Esboço do diagrama de classes para o problema apresentado (foram omitidas algumas setas para não sobrecarregar o diagrama: na resolução completa, deveriam ser incluídas).

PO-Janeiro2009-class.png

2.7. Diagrama de sequência (UML)

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).

PO-Janeiro2009-seq.png

2.8. Exercício de programação (loja)

2.9. Exercício de programação (formas de apresentação)

Uso do padrão Visitor: uma classe de visita por forma de apresentação.

import java.util.ArrayList;
abstract class Printable {
  public void add(Printable p) { throw new UnsupportedOperationException(); }
  public abstract String accept(Printer v);
}

class Paragraph extends Printable {
  public String accept(Printer v) { return v.showParagraph(this); }
}

class Image extends Printable {
  public String accept(Printer v) { return v.showImage(this); }
}

class Album extends Printable {
  public ArrayList<Printable> _printables = new ArrayList<Printable>();
  public void add(Printable p) { _printables.add(p); }
  public List<Printable> getPrintables() { return _printables; }
  public String accept(Printer v) { return v.showAlbum(this); }
}

class Page extends Album {
  public String accept(Printer v) { return v.showPage(this); }
}

class Book extends Album {
  public String accept(Printer v) { return v.showBook(this); }
}

As formas de apresentação são as definidas pela hierarquia de visita abaixo: Printer abstrai o conceito de apresentação; ShowWithBrackets representa a forma de apresentação presente no código original. Novas formas de apresentação resumem-se à definição de classes como esta última e não implicam quaisquer alterações no restante código.

interface Printer {
  String showParagraph(Paragraph p);
  String showImage(Image i);
  String showAlbum(Album a);
  String showPage(Page p);
  String showBook(Book b);
}

class ShowWithBrackets implements Printer {
  public String showParagraph(Paragraph p) { return "[paragraph]"; }
  public String showImage(Image i) { return "[image]"; }
  public String showAlbum(Album a) {
    String s = "[";
    for (Printable p: a.getPrintables()) s += p.accept(this);
    s += "]";
    return s;
  }
  public String showPage(Page p) { return showAlbum(p); }
  public String showBook(Book b) { return showAlbum(b); }
}

Note-se que se reutilizou a implementação para Album na apresentação de Page e de Book (tal como acontecia no código original).