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:
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?
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.
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);
}
}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);
}
}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);
}
}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);
}
}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.
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.
Hexaedro após a refatoração.Comparador após a refatoração.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 é:
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:
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.O diagrama de classe a seguir ilustra a estrutura descrita acima.
Qual padrão de projeto do catálogo GoF foi utilizado na solução proposta?