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

Questão 01

Uma empresa de desenvolvimento de software foi contratada para desenvolver aplicativos para uma instituição financeira, que possam ser executados em diferentes plataformas, como PC, celular e tablet. Para evitar a necessidade de criar diferentes soluções para cada plataforma, a empresa decidiu adotar um padrão de projeto que defina uma família de componentes para cada plataforma e uma implementação que os instancie de acordo com a plataforma-alvo na qual a aplicação será executada. O padrão de projeto adequado a essa implementação é:

a. Abstract Factory - fornece uma interface para criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.

b. Adapter - converte a interface de uma classe em outra interface, esperada pelos clientes, permitindo que certas classes trabalhem em conjunto, pois de outra forma seria impossível por causa de suas interfaces incompatíveis.

c. Prototype - especifica os tipos de objetos a serem criados usando uma instância prototípica e criar objetos copiando este protótipo.

d. Strategy - define uma família de algoritmos, encapsular cada um deles e fazê-los intercambiáveis, permitindo que o algoritmo varie independentemente dos clientes que o utilizam.

e. Template Method - define o esqueleto de um algoritmo em uma operação, postergando a definição de alguns passos para subclasses, permitindo que as subclasses redefinam certos passos de um algoritmo sem mudar sua estrutura.

Questão 02

Analise os seguintes itens:

  1. O padrão que, sem violar o encapsulamento e a captura, externalize o estado interno de um objeto e permita que posteriormente ele seja restaurado a esse estado, é o padrão de projeto Memento.
  2. Nos padrões de projeto (design patterns) estruturais, utilizam-se técnicas que valorizam um forte acoplamento entre as classes para favorecer o aprendizado e a portabilidade das aplicações.
  3. Para tratar de maneira uniforme objetos individuais em estruturas de árvores que representem hierarquias partes-todo, o padrão de projeto Composite é mais adequado que o padrão de projeto Decorator.

A análise permite concluir que:

a. apenas a alternativa I está correta.

b. apenas a alternativa II está correta.

c. apenas a alternativa III está correta.

d. apenas as alternativas I e II estão corretas.

e. apenas as alternativas I e III estão corretas.

Questão 03

No Unix, a permissão para acessar recursos do sistema é gerenciada em três níveis de granularidade: mundo, grupo e proprietário. Um grupo é uma coleção de usuários destinados a modelar alguma afiliação funcional. Cada usuário no sistema pode ser um membro de um ou mais grupos, e cada grupo pode ter zero ou mais usuários atribuídos a ele. A Figura 01 mostra três usuários que são atribuídos a todos os três grupos.

Figura 01
Figura 01

Se fôssemos modelar isso em software, poderíamos decidir ter objetos Usuário acoplados a objetos de Grupo e objetos de Grupo acoplados a objetos de Usuário. Em seguida, quando ocorrerem alterações, ambas as classes e todas as suas instâncias serão afetadas.

Uma abordagem alternativa seria introduzir "um nível adicional de abstração" - levar o mapeamento de usuários para grupos e grupos para os usuários, e torná-lo uma abstração em si mesmo, conforme apresentado na Figura 02. Isso oferece várias vantagens: Usuários e Grupos são desacoplados uns dos outros, muitos mapeamentos podem ser facilmente mantidos e manipulados simultaneamente, e a abstração de mapeamento pode ser estendida no futuro definindo classes derivadas. Qual padrão de projeto poderia resolver esse problema, promovendo uma "rede de relacionamento muitos-para-muitos" para "status de objeto completo".

Figura 02
Figura 02

a. Chain of Responsibility - evita o acoplamento do remetente de uma solicitação ao seu destinatário, dando a mais de um objeto a chance de tratar a solicitação.

b. Composite - compõe objetos em estrutura de árvore para representar hierarquias do tipo partes-todo.

c. Façade - fornece uma interface unificada para um conjunto de interfaces em um subsistema, definindo uma interface de nível mais alto que torna o subsistema mais fácil de usar.

d. Mediator - define um objeto que encapsula como um conjunto de objetos interage, promovendo o acoplamento fraco ao evitar que os objetos se refiram explicitamente uns aos outros.

e. Proxy - fornece um objeto representante (surrogate), ou um marcador de outro objeto, para controlar o acesso ao mesmo.

Questão 04

Uma das estratégias dominantes do projeto orientado a objetos é o "princípio aberto-fechado".

A Figura 03 demonstra como isso é rotineiramente alcançado - encapsular detalhes de interface em uma classe base e ocultar os detalhes de implementação em classes derivadas. Os clientes podem então acoplar-se a uma interface e não ter que experimentar a agitação associada à mudança: nenhum impacto quando o número de classes derivadas se altera e nenhum impacto quando a implementação de uma classe derivada muda.

Figura 03
Figura 03

Um ditado comum da comunidade de software há anos tem sido "maximizar a coesão e minimizar o acoplamento". A abordagem do projeto orientada a objetos mostrada na Figura 03 é sobre como minimizar o acoplamento. Uma vez que o cliente é acoplado apenas a uma abstração (isto é, uma interface), e não uma realização particular dessa abstração, o cliente poderia dizer que está praticando "acoplamento abstrato". Uma caracterização mais popular deste princípio de "acoplamento abstrato" é "programar para uma interface, não para uma implementação".

Os clientes devem preferir o "nível adicional de abstração" que uma interface (ou uma classe base abstrata) oferece. A interface capta a abstração que o cliente deseja exercer, e as implementações dessa interface são efetivamente ocultadas. Qual dos padrões de projeto apresentados a seguir explora esse conceito.

a. Adapter - converte a interface de uma classe em outra interface, esperada pelos clientes, permitindo que certas classes trabalhem em conjunto, pois de outra forma seria impossível por causa de suas interfaces incompatíveis.

b. Bridge - separa uma abstração da sua implementação, de modo que as duas possam variar independentemente.

c. Chain of Responsibility - evita o acoplamento do remetente de uma solicitação ao seu destinatário, dando a mais de um objeto a chance de tratar a solicitação.

d. Strategy - define uma família de algoritmos, encapsular cada um deles e fazê-los intercambiáveis, permitindo que o algoritmo varie independentemente dos clientes que o utilizam.

e. Visitor - representa uma operação a ser executada sobre os elementos da estrutura de um objeto, permitindo que você defina uma nova operação sem mudar as classes dos elementos sobre os quais opera.

Questão 05

A empresa XPTO foi contrata por um fabricante de monitores para modernizar o sistema responsável pela configuração do brilho e contraste dos mesmos, adicionando a possibilidade do usuário configurar a saturação do monitor. A listagem a seguir apresenta o código legado da empresa.

public class Monitor
{
private int option;
private int brightness;
private int contrast;
private boolean work;

public Monitor()
{
brightness = 4;
contrast = 4;
}

public void config()
{
Scanner scanner = new Scanner(System.in);
option = 0;
work = true;

while(work)
{
display();

String key = scanner.nextLine();
if("n".equals(key))
{
pressOption();
}
else if("-".equals(key))
{
pressMinus();
}
else if("+".equals(key))
{
pressPlus();
}
}

scanner.close();
}

public void display()
{
System.out.println(" Configuração");
System.out.println(displayBrightness());
System.out.println(displayContrast());
System.out.print((option == 3) ? "(*) " : " ");
System.out.print("Sair Não (-) (+) Sim\n ? ");
}

private String displayBrightness()
{
StringBuilder out = new StringBuilder();
if(option == 0)
{
out.append("(*) ");
}
else
{
out.append(" ");
}
out.append("Brilho ").append(displayValue(brightness));
return out.toString();
}

private String displayContrast()
{
StringBuilder out = new StringBuilder();
if(option == 1)
{
out.append("(*) ");
}
else
{
out.append(" ");
}
out.append("Contraste ").append(displayValue(contrast));
return out.toString();
}

private String displayValue(int value)
{
StringBuilder out = new StringBuilder();
for(int i = 0; i <= value; i++)
{
out.append(" ").append(i).append(" ");
}
return out.toString();
}

public void pressOption()
{
if(option == 0)
{
option = 1;
}
else if(option == 1)
{
option = 2;
}
else if(option == 2)
{
option = 0;
}
}

public void pressMinus()
{
if(option == 0)
{
if(brightness > 0)
{
brightness = brightness - 1;
}
}
else if(option == 1)
{
if(contrast > 0)
{
contrast = contrast - 1;
}
}
}

public void pressPlus()
{
if(option == 0)
{
if(brightness < 9)
{
brightness = brightness + 1;
}
}
else if(option == 1)
{
if(contrast < 9)
{
contrast = contrast + 1;
}
}
else if(option == 2)
{
work = false;
}
}

public static void main(String[] args)
{
Monitor monitor = new Monitor();

monitor.config();
}
}

Qual dos padrões de projeto apresentados seria adequado ser utilizado pela empresa XPTO para facilitar a execução do serviço contratado e futuras manutenções.

a. Command - encapsular uma solicitação como um objeto, desta forma permitindo parametrizar clientes com diferentes solicitações, enfileirar ou fazer o registro (log) de solicitações e suportar operações que podem ser desfeitas.

b. Decorator - agregar dinamicamente responsabilidades adicionais a um objeto.

c. Flyweight - usar compartilhamento para suportar eficientemente grandes quantidades de objetos de granularidade fina.

d. State - permite a um objeto alterar seu comportamento quando o seu estado interno muda, parecendo que o objeto alterou sua classe.

e. Template Method - define o esqueleto de um algoritmo em uma operação, postergando a definição de alguns passos para subclasses, permitindo que as subclasses redefinem certos passos de um algoritmo sem mudar sua estrutura.

Questão 06

Apresente o diagrama UML da solução utilizada pela empresa XPTO, adotando o padrão de projeto selecionado na questão 05.

Diagrama de classes
Diagrama de classes

Questão 07

Apresente a implementação da classe responsável pela configuração da saturação do monitor, conforme o diagrama UML apresentado na questão 06.

public class Saturation extends Option
{
public Saturation()
{
setValue(4);
}

@Override
public String display(boolean active)
{
return displayValue("Saturação ", active);
}

@Override
public void pressMinus()
{
if(getValue() > 0)
{
setValue(getValue() - 1);
}
}

@Override
public void pressPlus()
{
if(getValue() < 9)
{
setValue(getValue() + 1);
}
}
}

Questão Extra

Considere o domínio de escalonamento de processos ou agendador de tarefas (thread scheduling) apresentado na Figura 04.

Figura 04
Figura 04

Existem dois tipos de escalonadores de processos (PreemptiveThreadScheduler e TimeSlicedThreadScheduler) e dois tipos de sistemas operacionais ou plataformas (UnixPTS e WindowsPTS). Dada esta abordagem voltada a especialização, temos que definir uma classe para cada permutação dessas duas dimensões. Se adicionarmos uma nova plataforma (digamos, a Máquina Virtual do Java), nossa nova hierarquia de classes seria a apresentada na Figura 05.

Figura 05
Figura 05

Se tivéssemos três tipos de escalonadores de processos e quatro tipos de plataformas, ou se tivéssemos cinco tipos de escalonadores de processos e dez tipos de plataformas, o número de classes que teríamos que definir seria o produto do número de escalonadores de processos e do número de plataformas, conforme a hierarquia de classes apresentada na Figura 05.

Qual padrão de projeto se propõe a refatorar está hierarquia de herança exponencialmente explosiva em duas hierarquias ortogonais - uma para abstrações independentes de plataforma e outra para implementações dependentes de plataforma, conforme apresentado na Figura 06.

Figura 06
Figura 06

a. Abstract Factory - fornece uma interface para criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.

b. Bridge - separa uma abstração da sua implementação, de modo que as duas possam variar independentemente.

c. Builder - separa a construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção possa criar diferentes representações.

d. Factory Method - define uma interface para criar um objeto, mas deixa as subclasses decidirem qual classe a ser instanciada, permitindo a uma classe postergar (defer) a instanciação às subclasses.

e. Mediator - define um objeto que encapsula como um conjunto de objetos interage, promovendo o acoplamento fraco ao evitar que os objetos se refiram explicitamente uns aos outros, permitindo que se varie suas interações independentemente.