Ybadoo - Soluções em Software Livre
Turmas
2º Semestre de 2014

Questão 01

Os padrões de projeto (design patterns) apresentados no livro Design Patterns: Elements of Reusable Object-Oriented Software, publicado em 1995 por Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, também conhecidos como a "Gangue dos Quatro" (Gang of Four) ou simplesmente "GoF", são organizados em três famílias, sendo:

  1. Situacional, estrutural e complementar.
  2. Criacional, evolutiva e contingencial.
  3. Compartimental, vinculada e comportamental.
  4. Criacional, funcional e orientada a requisitos.
  5. Criacional, estrutural e comportamental.

Questão 02

Em um sistema de software para controlar pedidos para entrega em domicílio, deve haver uma funcionalidade que permita que o atendente solicite a repetição de um pedido anteriormente feito por um cliente. O gerente do restaurante informou que essa funcionalidade aumentaria a agilidade no atendimento aos clientes, visto que muitos deles tendem a fazer pedidos similares aos que já fizeram anteriormente. Ao usar essa funcionalidade, o atendente do restaurante seleciona um pedido cuja composição corresponde a produtos normalmente requisitados pelos clientes e solicita ao sistema a construção de um novo pedido igual ao selecionado. Esse novo pedido pode, então, ser alterado pelo atendente se o cliente solicitar a adição de novos produtos do cardápio, por exemplo. Portanto, a parte principal dessa funcionalidade corresponde a criar uma cópia de um pedido a partir de pedido preexistente. Na implementação dessa funcionalidade, seu desenvolvedor deve utilizar qual padrão de projeto do catálogo GoF (Gang of Four), dentre os listados abaixo?

  1. Builder
  2. Factory Method
  3. Command
  4. Abstract Factory
  5. Prototype

Durante o desenvolvimento de um sistema para comparação das propriedades métricas de sólidos platônicos, os desenvolvedores implementaram uma classe para cada sólido platônico existente, conforme apresentado a seguir.

Arquivo Tetraedro.java

package com.ybadoo.tutoriais.poo;

/**
* Representancao de um tetraedro
*/
public class Tetraedro
{
/**
* Valor da aresta do tetraedro
*/
private double aresta;

/**
* Construtor para inicializar o valor da aresta do tetraedro
*
* @param aresta valor da aresta do tetraedro
* @throws IllegalArgumentException valor da aresta do tetraedro invalido
*/
public Tetraedro(double aresta) throws IllegalArgumentException
{
if(aresta >= 0.0)
{
this.aresta = aresta;
}
else
{
throw new IllegalArgumentException("Valor da aresta do "
+ "tetraedro é inválido");
}
}

/**
* Retornar a area do tetraedro
*
* @return area do tetraedro
*/
public double area()
{
return Math.sqrt(3.0) * Math.pow(aresta, 2.0);
}

/**
* Retornar o valor da aresta do tetraedro
*
* @return valor da aresta do tetraedro
*/
public double getAresta()
{
return aresta;
}

/**
* Retornar o volume do tetraedro
*
* @return volume do tetraedro
*/
public double volume()
{
return (Math.sqrt(2.0) / 12.0) * Math.pow(aresta, 3.0);
}
}

Arquivo Hexaedro.java

package com.ybadoo.tutoriais.poo;

/**
* Representancao de um hexaedro
*/
public class Hexaedro
{
/**
* Valor da aresta do hexaedro
*/
private double aresta;

/**
* Construtor para inicializar o valor da aresta do hexaedro
*
* @param aresta valor da aresta do hexaedro
* @throws IllegalArgumentException valor da aresta do hexaedro invalido
*/
public Hexaedro(double aresta) throws IllegalArgumentException
{
if(aresta >= 0.0)
{
this.aresta = aresta;
}
else
{
throw new IllegalArgumentException("Valor da aresta do "
+ "hexaedro é inválido");
}
}

/**
* Retornar a area do hexaedro
*
* @return area do hexaedro
*/
public double area()
{
return 6.0 * Math.pow(aresta, 2.0);
}

/**
* Retornar o valor da aresta do hexaedro
*
* @return valor da aresta do hexaedro
*/
public double getAresta()
{
return aresta;
}

/**
* Retornar o volume do hexaedro
*
* @return volume do hexaedro
*/
public double volume()
{
return Math.pow(aresta, 3.0);
}
}

Arquivo Octaedro.java

package com.ybadoo.tutoriais.poo;

/**
* Representancao de um octaedro
*/
public class Octaedro
{
/**
* Valor da aresta do octaedro
*/
private double aresta;

/**
* Construtor para inicializar o valor da aresta do octaedro
*
* @param aresta valor da aresta do octaedro
* @throws IllegalArgumentException valor da aresta do octaedro invalido
*/
public Octaedro(double aresta) throws IllegalArgumentException
{
if(aresta >= 0.0)
{
this.aresta = aresta;
}
else
{
throw new IllegalArgumentException("Valor da aresta do "
+ "octaedro é inválido");
}
}

/**
* Retornar a area do octaedro
*
* @return area do octaedro
*/
public double area()
{
return 2.0 * Math.sqrt(3.0) * Math.pow(aresta, 2.0);
}

/**
* Retornar o valor da aresta do octaedro
*
* @return valor da aresta do octaedro
*/
public double getAresta()
{
return aresta;
}

/**
* Retornar o volume do octaedro
*
* @return volume do octaedro
*/
public double volume()
{
return (Math.sqrt(2.0) / 3.0) * Math.pow(aresta, 3.0);
}
}

Arquivo Dodecaedro.java

package com.ybadoo.tutoriais.poo;

/**
* Representancao de um dodecaedro
*/
public class Dodecaedro
{
/**
* Valor da aresta do dodecaedro
*/
private double aresta;

/**
* Construtor para inicializar o valor da aresta do dodecaedro
*
* @param aresta valor da aresta do dodecaedro
* @throws IllegalArgumentException valor da aresta do dodecaedro invalido
*/
public Dodecaedro(double aresta) throws IllegalArgumentException
{
if(aresta >= 0.0)
{
this.aresta = aresta;
}
else
{
throw new IllegalArgumentException("Valor da aresta do "
+ "dodecaedro é inválido");
}
}

/**
* Retornar a area do dodecaedro
*
* @return area do dodecaedro
*/
public double area()
{
return 3.0 * Math.sqrt(25.0 + 10.0 * Math.sqrt(5.0)
* Math.pow(aresta, 2.0));
}

/**
* Retornar o valor da aresta do dodecaedro
*
* @return valor da aresta do dodecaedro
*/
public double getAresta()
{
return aresta;
}

/**
* Retornar o volume do dodecaedro
*
* @return volume do dodecaedro
*/
public double volume()
{
return 1.0/4.0 * (15.0 + 7.0 * Math.sqrt(5.0)) * Math.pow(aresta, 3.0);
}
}

Arquivo Icosaedro.java

package com.ybadoo.tutoriais.poo;

/**
* Representancao de um icosaedro
*/
public class Icosaedro
{
/**
* Valor da aresta do icosaedro
*/
private double aresta;

/**
* Construtor para inicializar o valor da aresta do icosaedro
*
* @param aresta valor da aresta do icosaedro
* @throws IllegalArgumentException valor da aresta do icosaedro invalido
*/
public Icosaedro(double aresta) throws IllegalArgumentException
{
if(aresta >= 0.0)
{
this.aresta = aresta;
}
else
{
throw new IllegalArgumentException("Valor da aresta do "
+ "icosaedro é inválido");
}
}

/**
* Retornar a area do icosaedro
*
* @return area do icosaedro
*/
public double area()
{
return 5.0 * Math.sqrt(3.0) * Math.pow(aresta, 2.0);
}

/**
* Retornar o valor da aresta do icosaedro
*
* @return valor da aresta do icosaedro
*/
public double getAresta()
{
return aresta;
}

/**
* Retornar o volume do icosaedro
*
* @return volume do icosaedro
*/
public double volume()
{
return 5.0/12.0 * (3.0 + Math.sqrt(5.0)) * Math.pow(aresta, 3.0);
}
}

Mas quando os desenvolvedores foram implementar a classe responsável pela comparação das propriedades métricas de sólidos platônicos, identificaram um problema, pois teriam que implementar uma função para cada uma das combinações possíveis, conforma apresentado na classe a seguir.

Arquivo Comparador.java

package com.ybadoo.tutoriais.poo;

/**
* Comparador das propriedades metricas de solidos platonicos
*/
public class Comparador
{
/**
* Comparar a area de dois solidos platonicos
*
* @param obj1 instancia do primeiro tetraedro
* @param obj2 instancia do segundo tetraedro
* @return
* 1 caso a area do primeiro seja maior do que a area do segundo,
* -1 caso a area do segundo seja maior do que a area do primeiro,
* 0 caso as areas dos dois sejam iguais
*/
public int area(Tetraedro obj1, Tetraedro obj2)
{
if(obj1.area() > obj2.area())
{
return 1;
}

if(obj1.area() < obj2.area())
{
return -1;
}

return 0;
}

/**
* Comparar a area de dois solidos platonicos
*
* @param obj1 instancia do tetraedro
* @param obj2 instancia do hexaedro
* @return
* 1 caso a area do tetraedro seja maior do que a area do hexaedro,
* -1 caso a area do hexaedro seja maior do que a area do tetraedro,
* 0 caso as areas dos dois sejam iguais
*/
public int area(Tetraedro obj1, Hexaedro obj2)
{
if(obj1.area() > obj2.area())
{
return 1;
}

if(obj1.area() < obj2.area())
{
return -1;
}

return 0;
}

/* .... */

/**
* Comparar o volume de dois solidos platonicos
*
* @param obj1 instancia do primeiro tetraedro
* @param obj2 instancia do segundo tetraedro
* @return
* 1 caso o volume do primeiro seja maior do que o volume do segundo,
* -1 caso o volume do segundo seja maior do que o volume do primeiro,
* 0 caso os volumes dos dois sejam iguais
*/
public int volume(Tetraedro obj1, Tetraedro obj2)
{
if(obj1.volume() > obj2.volume())
{
return 1;
}

if(obj1.volume() < obj2.volume())
{
return -1;
}

return 0;
}

/**
* Comparar o volume de dois solidos platonicos
*
* @param obj1 instancia do tetraedro
* @param obj2 instancia do hexaedro
* @return
* 1 caso o volume do tetraedro seja maior do que o volume do hexaedro,
* -1 caso o volume do hexaedro seja maior do que o volume do tetraedro,
* 0 caso os volumes dos dois sejam iguais
*/
public int volume(Tetraedro obj1, Hexaedro obj2)
{
if(obj1.volume() > obj2.volume())
{
return 1;
}

if(obj1.volume() < obj2.volume())
{
return -1;
}

return 0;
}

/* .... */
}

Refatore o sistema apresentado, empregando os padrões de projeto do catálogo GoF, de forma que a classe Comparador possa realizar facilmente a comparação das propriedades métricas de sólidos platônicos.

  1. apresente o diagrama de classes em UML da solução proposta.
  2. quais foram os padrões de projeto do catálogo GoF que você utilizou na refatoração? Justifique a escolha dos padrões utilizados.
  3. apresente a codificação na linguagem de programação Java da classe Hexaedro após a refatoração.
  4. apresente a codificação na linguagem de programação Java da classe Comparador após a refatoração.

Questão 04

Durante o desenvolvimento de um sistema para suporte a uma rede social, um desenvolvedor decidiu criar a facilidade de uma pessoa ter uma lista de amigos para poder enviar e-mails, postagens e/ou fotos. Essa lista pode conter um número indefinido de amigos ou de outras listas de amigos, criando uma estrutura recursiva. O padrão de projeto do catálogo GoF que descreve essa estrutura é:

  1. Abstract factory
  2. Chain of responsibility
  3. Composite
  4. Iterator
  5. Module

Questão Extra

Deseja-se que uma aplicação possa manipular diferentes tipos de bancos de dados de modo transparente às classes que necessitam de serviços de acesso a dados. Inicialmente será necessário fornecer suporte a bancos de dados XML e SQL, entretanto, novos tipos poderão ser futuramente adicionados. A solução proposta é a seguinte:

  1. Uma classe abstrata (DB) será responsável por instanciar um objeto correspondente ao tipo de banco de dados desejado. Isso será feito através do método estático getDB(), que retornará um objeto de uma de suas subclasses concretas, de acordo com o parâmetro (tipo) passado.
  2. O objeto criado no passo anterior irá instanciar conexões e consultas correspondentes ao tipo de DB criado; isto é, caso um DB XML tenha sido instanciado, apenas consultas XML e conexões XML serão instanciadas; caso um DB SQL tenha sido instanciado, apenas consultas SQL e conexões SQL serão instanciadas.

O diagrama de classe a seguir ilustra a estrutura descrita acima.

Diagrama de Classe
Diagrama de Classe

Qual padrão de projeto do catálogo GoF foi utilizado na solução proposta?

  1. Adapter
  2. Builder
  3. Composite
  4. Abstract Factory
  5. Chain of Responsibility