sexta-feira, 22 de julho de 2016

Padrões de nomenclatura

Classes e interfaces - A primeira letra deve ser maiúscula e, se várias palavras forem escritas juntas para formar o nome, a primeira letra de cada palavra interna deve ser maiúscula (um formato chamado de "camelCase").
Para classes, os nomes devem normalmente ser substantivos(nome de "coisas"). Por exemplo: Dog//Cachorro
Para interfaces, os nomes devem normalmente ser adjetivos(características, qualidade), Por exemplo: Runnable // Executável

Métodos - A primeira letra deve ser minúscula, e depois as regras camelCase normais devem ser usadas. Além disso, os nomes devem normalmente ser pares de verbo-substantivo. Por exemplo: doCalculation // fazerCálculo

Variáveis - Como nos métodos, o formato camelCase deve ser usado, comecando com uma letra minúscula. É recomendado usar nomes curtos e significativos. Por exemplo:  buttonWidth // larguraDoBotao

Constantes - As constantes Java sào criadas marcando-se variáveis como static e final. Elas devem ser nomeadas usando-se letras maiúsculas como caracteres underscore como separadores. Por exemplo: MIN_HEIGHT // ALTURA_MINIMA

Exceções - Os nomes devem revelar a causa da exceção e devem terminar com o sufixo que representa a sua hierarquia de exceção: Exception ou Error. Por exemplo, em ArithemeticException sabemos que se trata de uma classe derivada de Exception, e não de Error, que foi causada por algum problema em uma operação aritmética.


Algumas classes com utilidade especifica têm formas especificas de serem nomeadas. A seguir são listados alguns modelos de nomenclatura para estes conjuntos de classes, baseados nas regras anteriores.

Entidades - O nome de uma entidade é uma exceção ao principio de Preferência de Domínio Técnico. Nomes de entidades não devem conter sufixo ou prefixos de nenhum tipo, nem mesmo o popular Entity. Nomes de entidades, são exatamente isso, nomes. Substantivos que são recolhidos do dominio do problema e que normalmente guiam o objetivo ou a operação do software.

Repositório - A nomenclatura do padrão Repository segue o modelo: [Entidade] Repository.
Esta nomenclatura segue o principio de Preferência de Dominio Técnico deixando o nome do padrão no fim do nome. O nome é precedido pelo nome da entidade a que este repositório se refere.

Serviço - O padrão Service tem duas peças: a interface do serviço e a implementação do serviço. A nomenclatura para a interface do padrão Service segue o modelo: [Proposito]Service. Esta nomenclatura segue o principio de Preferência de Dominio Tecnico deixando o nome do padrão no fim do nome. O nome é precedido pela descrição do proposito em forma resumida, por exemplo: EmailSendingService.
O nome da implementação do serviço segue o modelo: [Tecnologia][Proposito]Service, em que ao nome da interface do serviço é adicionado um prefixo que denota o tipo de tecnologia ou algoritmo que o serviço utiliza para satisfazer a interface, por exemplo: JavaMailEmailSendingService

DAO - O padrão DAO, semelhante ao padrão Service tem duas peças: a interface do serviço/estratégia e a implementação. Para classes de DAO associados a entidades, o nome da entidade é adicionado como prefixo para distinguir entre os contratos de cada entidade. O nome da interface segue o modelo [Entidade]DAO e o da implementação o modelo: [Tecnologia][Entidade]DAO. Esta nomenclatura segue o principio de Preferência de Dominio Técnico deixando o nome do padrão no fim do nome.
O nome da implementação começa com o nome da tecnologia de persistência que a implementação do DAO usa, seguindo pelo nome da interface que está sendo implementada, por exemplo JdbcCustomerDAO.

quinta-feira, 14 de julho de 2016

O que é inversão de Dependência?

Princípio da Inversão de Dependência (Dependency Inversion Principle), ou simplesmente DIP, faz parte do principio SOLID:
  • Single Responsabilty Principle
  • Open/Closed
  • Liskov Substitution Principle
  • Interface Segregation
  • Dependency Inversion Principle
Definição:
  • Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações;
  • Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.
Vantagens:
  • Melhora na manutenibilidade, pois o código fica mais flexível e reutilizável.
  • Melhora na testabilidade, pois não precisamos conhecer detalhes da dependência.
Exemplo:
O clássico exemplo do botão e da lâmpada, onde ambas as classes são concretas:

1
2
3
4
5
6
7
8
9
10
public class Botao
{
    private Lampada lampada;
    public void Acionar()
    {
        if (condicao)
            lampada.Ligar();
    }
}

O design acima viola o DIP uma vez que Botão depende de uma classe concreta Lampada. Ou seja, Botão conhece detalhes de implementação ao invés de termos identificado uma abstração para o design.

Que abstração seria essa? Botão deve ser capaz de tratar alguma ação e ligar ou desligar algum dispositivo, seja ele qual for: uma lâmpada, um motor, um alarme, etc.

Aplicando o DIP:

A solução abaixo inverte a dependência de botão para a lâmpada, fazendo com que ambos agora dependam da abstração Dispositivo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Botao
{
    private Dispositivo dispositivo;
    public void Acionar()
    {
        if (condicao)
            dispositivo.Ligar();
    }
}
public interface Dispositivo
{
    void Ligar();
    void Desligar();
}
public class Lampada implements Dispositivo
{
    public void Ligar()
    {
        // ligar lampada
    }
    public void Desligar()
    {
        // desligar lampada
    }
}

O Princípio da Inversão de Dependência é um princípio essencial para um bom design orientado a objetos, focada na resolução do problema e flexível quanto a detalhes de implementação. Identificar abstrações e inverter as dependências garantem que o software seja mais flexível e robusto, estando melhor preparado para mudanças.