Qual a Diferença entre UI e UX


Atualmente tem se falado muito sobre design UX nos softwares, e juntamente com o aparecimento deste acrônimo, apareceram também dúvidas sobre qual a diferença entre o design UI que é o design para a interface do usuário do software, com o termo design UX que está relacionado com a experiência do usuário na utilização do software. Neste post você vai conhecer a diferença entre UI e UX.

Explicando de forma muito resumida o termo UX que é um acrônimo para Experiência do Usuário (User Experience) é um campo mais analítico e técnico, enquanto que a UI que é um acrônimo para Interface de Usuário (User Interface) está mais relacionada com a camada visual.

Os acrônimos têm sido utilizados já há algum tempo, mas a ideia por trás das siglas vem sendo aplicada há muito mais tempo ainda.

Apesar dos dois tipos de design serem muito importantes para o software e trabalharem próximos, as suas funções são completamente diferentes. A boa experiência de um software se inicia com o design UX e é finalizado com o design UI, ambos são essenciais para o sucesso do software.

A interface do usuário normalmente é parte da experiência do usuário, mas pode existir a experiência do usuário sem necessariamente existir uma interface.

O Que é UX

O termo Experiência do Usuário foi criado por Donald Norman, co-fundador da Nielsen Norman Group Design Consultancy nos anos 90.

O design UX é o processo de desenvolvimento e melhoria da qualidade da interação entre o usuário e o seu software. Ele é responsável pelo processo de pesquisa, teste, desenvolvimento, conteúdo e prototipação dos testes para resultados de qualidade.

O design UX envolve a atitude, o comportamento e sentimentos do usuário, na utilização do software. Ele também inclui a percepção do usuário nos aspectos do sistema tais como, utilidade, facilidade de uso e eficiência. A experiência do usuário pode ser considerada subjetiva, porque se trata da percepção e pensamento com respeito ao sistema.

A dinâmica da experiência do usuário está constantemente em modificação devido às alterações das circunstâncias de uso, alterações individuais de sistema, bem como alterações do contexto do uso.

O Que é UI

A função do design UI é proporcionar ao usuário um local onde ele possa interagir com o software de forma simples, amigável e eficiente, de preferência que ele possa inserir poucas informações para que o software execute a operação desejada.

O design UI normalmente se preocupa com a apresentação e a aparência da tela do software para o usuário, conhecida na área de software como Interface Gráfica do Usuário (GUI - Graphical User Interface). O objetivo principal é fazer com que a interação entre o usuário e o software seja a mais simples e eficiente, possível, e que também proporcione uma boa experiência para o usuário.

Diferença entre UI e UX

Um exemplo que achei interessante para diferenciar o design UX do design UI, foi um que solicitava que a equipe de design definisse qual a melhor forma de apresentar uma tela de login com opção de cadastro para o usuário.

No design UI a preocupação está em como posicionar os botões, caixas de texto, definir cores, layout da tela, seleção dos campos necessários para preenchimento dos dados do usuário, etc.

No design UX, a primeira pergunta seria, qual é o público que a aplicação deseja atingir, se for um público que utiliza redes sociais, ao invés de termos o login com opção de cadastro, poderíamos ter botões de login integrados nas principais redes sociais, onde este público já possui cadastro, melhorando desta forma a experiência do usuário.

Nesse exemplo fica claro como os dois tipos de design são importantes na definição das telas do projeto.

Podemos ter softwares com interfaces muito bem feitas, com uma aparência excelente, mas que são muito complicadas de trabalhar e não são intuitivas, neste caso temos um bom design UI e um design UX ruim.

E também podemos ter casos de interfaces com uma aparência não tão bem elaborada, mas que são extremamente fáceis de trabalhar e intuitivas, neste caso temos um bom design UX e um design UI mais simplificado.

Nesse post mencionei a diferença entre UI e UX para a área de software, mas estes designs podem ser aplicados em vários campos da indústria, como por exemplo, equipamentos para área médica, para área automobilística, entre outros.

Post Relacionado:
The Most Important Rule in UX Design that Everyone Breaks (A regra mais importante do Design UX que todo mundo quebra)

8 Dicas de Boas Práticas de Programação


Quando escrevemos um código para o desenvolvimento de um software, independentemente da linguagem de programação, devemos nos preocupar desde o início em seguir as boas práticas de programação, já pensando em uma manutenção futura, uma melhoria, uma inclusão de nova funcionalidade entre outras alterações que são necessárias durante todo o ciclo de desenvolvimento do software.

Desde o inicio do desenvolvimento é importante que o desenvolvedor se preocupe com a legibilidade, com o estilo e o design do código. O software deve ser escrito tendo em mente que outro desenvolvedor poderá fazer a manutenção.

Devemos ter respeito pelo próximo desenvolvedor que vai dar manutenção ou até pensar em nós mesmos, que depois de um tempo, não vamos lembrar qual a função de determinada parte do código.

Por esta razão resolvi citar algumas boas práticas de programação neste post, que podem ser seguidas para facilitar a nossa vida de desenvolvedor como de outros desenvolvedores que irão atualizar o nosso código.

1. Comentários

O comentário deve se escrito de forma que possamos entender o que o código faz, sem a necessidade de interpretar o código.

Deve-se evitar comentários óbvios que vão somente poluir o código, e não vão trazer nenhum benefício para o entendimento do código.

O comentário deve ser claro de forma que após vários anos você ou outro desenvolvedor seja capaz de entender o que o código faz.

Faça os comentários conforme for codificando, porque provavelmente você não vai ter tempo de voltar  para incluir o comentário e também não vai lembrar dos detalhes do código. O que pode ser óbvio agora não vai ser tão óbvio alguns dias ou semanas depois que você finalizar o código.

É preciso ter muito cuidado com a estrutura do código e com a utilização de algoritmos por exemplo, um algoritmo de ordenação que utiliza equações matemáticas, dificilmente será fácil de entender simplesmente lendo o código, por isto algoritmos devem ser muito bem comentados.

2. Consistência

Durante a escrita é necessário manter a consistência na formatação dos espaços utilizados no código. Normalmente as ferramentas de programação permitem que o desenvolvedor selecione a forma de fazer a indentação. O desenvolvedor pode escolher entre Espaços e Tabs. O correto é selecionar uma das formas e seguir esta forma durante toda a escrita do código.

Se for selecionado Tab utilize somente Tab, se selecionado Espaço, utilize somente Espaço, mas nunca misture os dois, porque se utilizar as duas formas indiscriminadamente o código vai ficar desalinhado dificultando o entendimento.

3. Indentação

Na codificação o recurso de indentação deve ser utilizado para facilitar a leitura e o entendimento do código, principalmente em cláusulas com controle de fluxo, como por exemplo o IF, FOR, WHILE.

A indentação facilita a leitura e entendimento das cláusulas de controle de fluxo. É bem mais fácil entender o próximo comando de uma cláusula IF, se o código estiver indentado, por exemplo, utilizando pseudocódigo.  O exemplo 1 mostra um código com indentação e o exemplo 2 sem a indentação.

Exemplo 1:

Se condicao1 Entao
Execute o comando1
Senao
Execute o comando 2
Fim Se

Exemplo 2:

Se condicao1 Entao
   Execute o comando1
Senao
   Execute o comando 2
Fim Se

O exemplo 1 é bem mais fácil de entender do que o exemplo 2

4. Número Máximo de Linhas

Defina um número máximo de caracteres por linha de código e comentários, de modo a evitar que seja necessário utilizar o scroll horizontal para ler uma linha de código ou do comentário.

5. Legibilidade

Para facilitar o entendimento das expressões utilize espaço após os operadores e vírgulas. O exemplo 1 mostra uma expressão com espaços e o exemplo 2 sem os espaços.

Exemplo 1:

total_pedido = valor_objeto * qtdade

Exemplo 2:

total_pedido=valor_objeto*qtdade

O exemplo 1 é bem mais fácil de ser lido e interpretado do que o exemplo 2.

Separe blocos de código com linhas em branco para facilitar a visualização dos blocos, fazendo uma boa separação de funcionalidades de cada bloco.

Evite utilizar mais de uma declaração por linha. No momento da manutenção, sempre fica mais complicado e demorado interpretar várias declarações na mesma linha ao invés de cada linha.

6. Nomenclaturas

Ao escolher os nomes de variáveis, constantes, nomes de métodos, propriedades, selecione nomes que façam sentido dentro do contexto do software. Evite utilizar palavras ou letras que não deixam claro qual operação está sendo efetuada. Normalmente o nome deve dizer “O que” ao invés de “Como” está sendo feita a operação.

Por exemplo, para fazermos uma operação de cálculo de juros, no exemplo 1 os nomes das variáveis deixam claro o que cada uma representa, no exemplo 2 não é possível saber o que está sendo multiplicado. Os nomes de variáveis devem ser descritivos.

Exemplo 1:

valor_total = valor * taxa_juros

Exemplo 2:

x = y * z

Letras podem ser utilizadas em operações como por exemplo, loops (FOR).

Alguns nomes de métodos/ funções/sub-rotinas utilizam concatenação de palavras, portanto utilize uma mistura de letras maiúsculas e minúsculas ou underscore para separar as palavras. Um bom nome para um método/função/sub-rotina que faça o cálculo de juros seria Calcula_Juros() ou CalculaJuros()

A forma de utilizar letra maiúscula ou minúscula para iniciar os nomes de métodos/funções/ sub-rotinas ou variáveis dependem dos padrões e regras de cada linguagem de programação. Por isto procure conhecer quais são os padrões e regras da linguagem em que você vai trabalhar.

Não utilizar números no meio do código que tem um significado específico. Por exemplo, se for utilizar o número 100 para definir o número máximo de itens em um pedido, ao invés de utilizar o número procure utilizar uma constante como, por exemplo NUM_MAX_ITENS_PEDIDO.

7. Organização

Faça uma divisão de métodos/sub-rotinas/funções longas ou complexas de código em módulos menores. Uma boa dica a se seguir se for possível, é que cada módulo do método/sub-rotina/função tenha no máximo o tamanho da tela do editor de textos da linguagem de programação que está sendo utilizada.

Faça um arranjo ou separação do código de uma forma lógica em arquivos e pastas, de modo a ficar fácil o entendimento da estrutura em que foi projetado o código.

8. Verificações

Faça testes nos retornos de status. Por exemplo, no momento de ler ou escrever um arquivo nem sempre o programa consegue executar com sucesso, portanto teste o retorno antes de prosseguir com o restante do código.

Quando ocorrerem erros deve-se procurar uma recuperação ou tratar a falha de forma graciosa, tentando continuar com a tarefa se for possível. Isto é o que programas robustos costumam fazer.

Quando ocorrer uma falha ou erro procure informar o usuário de uma forma amigável, através de mensagens com conteúdo simples, que ele possa entender qual foi o problema. Sempre é bom gravar um arquivo de log com informações que sejam úteis, para que o desenvolvedor possa entender qual foi o problema.

Procure encapsular funções construídas e bibliotecas de terceiros em seus próprios métodos, assim quando uma biblioteca de terceiro sofrer alteração não é necessário que seja revisado todo o código, e sim o método que você criou para encapsular a biblioteca. Isto também facilita o teste e debug da biblioteca, porque o código está escrito somente em um local.

Estas são apenas algumas dicas de boas práticas de programação, naturalmente existem muitas outras. Se você quiser acrescentar mais alguma dica deixe um comentário, que com certeza serão muito úteis para a comunidade de desenvolvedores.


Como Tratar Erros na Biblioteca Android Wear

O Google oferece um variedade de serviços que podem ser utilizados nos dispositivos Android, como acesso aos mapas, google+, drive, wallet, google cloud entre outros.

Apesar destes serviços não fazerem parte da plataforma de desenvolvimento do Android, é possível ter acesso à estes serviços utilizando o Google Services API, e distribuir as aplicações no Google Play. Esta biblioteca está disponível para dispositivos com versão 2.3 ou superior.

Com o lançamento de novos dispositivos Android como por exemplo, relógios (smartwatch) foi lançada também a biblioteca android para este tipo de dispositivo o Android Wear API.
 
Como todo serviço esta biblioteca utiliza a classe GoogleApiClient.Builder(Context) para definir a API a ser utilizada na aplicação através da chamada do método addApi(api), e a conexão com o serviço é feita através do método connect() da classe GoogleApiClient.

O método connect() é chamado para estabelecer uma conexão com a biblioteca do Google Play Services e pode retornar um código de erro se a API não estiver disponível. Existem 2 formas do método connect() retornar o erro de conexão ConnectionResult.API_UNAVAILABLE:
  1. Quando chamada a bibllioteca Wearable.API em dispositivos rodando Android 4.2 (API versão 17) ou inferior.
  2. Quando chamada a biblioteca Wearable.API e a mesma não está disponível em alguma aplicação do dispositivo que já utiliza esta biblioteca, ou o dispositivo não é do tipo wearable, como por exemplo, um smartwatch
Se for utilizada uma única instância da classe GoogleApiClient para verificar a disponibilidade de dois serviços, como por exemplo Drive e Wearable, e a biblioteca do Wearable retornar ConnectionResult.API_UNAVAILABLE, a biblioteca do Drive também vai receber o mesmo resultado no momento de fazer a conexão, ou seja indisponível, fazendo com que a aplicação não funcione corretamente.

Portanto no caso de utilizar a biblioteca do Android Wear, devem ser utilizadas pelo menos duas instâncias diferentes da classe GoogleApiClient para fazer a conexão com os serviços do Google Service. No exemplo dado neste post é necessário criar uma instância da classe GoogleApiClient para se conectar à biblioteca do Android Wear e a outra para o serviço do Google Drive..

Dicas de Ferramentas para Gerenciar Aplicações Android

O Console de Desenvolvedor do Google Play, possui várias ferramentas que permitem fazer um melhor gerenciamento da publicação e distribuição de uma aplicação Android.

Quando é criada uma conta no Google Play, além das informações que devem ser preenchidas para a publicação, também existem algumas ferramentas que podem ser configuradas para melhorar o gerenciamento da aplicação.

A seguir menciono duas ferramentas úteis para o acompanhamento da aplicação, tanto por parte do desenvolvedor, como para outras equipes da empresa como por exemplo, a equipe de marketing, que pode estar acompanhando a opinião dos usuários com relação a utilização da aplicação.

A primeira ferramenta é o Email de Alerta, que pode ser configurado para informar sobre mudanças súbitas nas estatísticas de instalações da aplicação, problemas com a aplicação ou sobre as avaliações que os usuários estão fazendo da aplicação. Para configurar o email de alerta, entre na tela de Configurações do Console de Desenvolvedor no item Preferências de Email e altere a configuração de Alertas.

A segunda ferramenta que vale a pena conferir é a Dicas de Otimização, que pode ser acessada no Console do Desenvolvedor, selecionando-se a aplicação publicada. As Dicas de Otimização possuem informações para melhorar a aplicação tais como, informação de atualizações de bibliotecas como por exemplo, a API do Google Maps.

Além das ferramentas mencionadas, existe também a biblioteca de publicação para o desenvolvedor (Google Play Developer Publishing API), que permite automatizar várias tarefas relacionadas com a produção e distribuição da aplicação. Esta biblioteca possui funcionalidades similares à existente no Console de Desenvolvedor tais como, upload de novas versões da aplicação, lançamento de aplicações em várias fases como versão beta e produção.

A biblioteca de publicação para o desenvolvedor pode ser utilizada para criar a sua própria ferramenta de administração de aplicações publicadas no Google Play. Atualmente a biblioteca possui dois componentes, um para gerenciar as assinaturas e aquisições feitas na própria aplicação (Assinaturas e Aquisições In-App) e  outra para gerenciar as publicações.

Na documentação da biblioteca do Google Play Developer Publishing API, existem exemplos de utilização em várias linguagens de programação, assim como bibliotecas cliente para facilitar a interação com a API, ao invés de utilizar REST API diretamente com HTTP.


Algoritmo InsertionSort Implementado em Java

O algoritmo InsertionSort  é um algoritmo simples de ordenação, que pode ser utilizado para ordenar uma quantidade pequena de números.

Este algoritmo é conhecido por sua simplicidade e facilidade de implementação. A ordenação é feita de uma forma similar ao que as pessoas utilizam para ordenar cartas de um baralho. Normalmente se mantêm as cartas em uma mão e durante o jogo, conforme vão recebendo as cartas, colocam as cartas recebidas na mão de uma forma ordenada.

A classe InsertionSort foi implementada em Java com dois métodos, o método sortAsc(int[] values) que faz a ordenação de uma matriz de números inteiros em ordem crescente e o método sortDesc(int[] values) que faz a ordenação em ordem decrescente.

/**
 * Faz a ordenação de uma matriz de números inteiros.
 */
public class InsertionSort {

    /*
     * Faz a ordenação de forma crescente
     */
    public int[] sortAsc(int[] values){
        int key = 0;
        int i = 0;
        
        for (int j = 1; j < values.length; j++) {
            key = values[j];
            i = j - 1;
            while (i >= 0 && values[i] > key) {
                values[i + 1] = values[i];
                i = i - 1;
            }            
            values[i + 1] = key;
        }        
        return values;
    }
    
    /*
     * Faz a ordenação de forma decrescente
     */
    public int[] sortDesc(int[] values){
        int key = 0;
        int i = 0;
        
        for (int j = 1; j < values.length; j++) {
            key = values[j];
            i = j - 1;
            while (i >= 0 && values[i] < key) {
                values[i + 1] = values[i];
                i = i - 1;
            }            
            values[i + 1] = key;
        }        
        return values;
    }
}

O algoritmo ordena os números de entrada da matriz na própria matriz, fazendo uma reorganização dos números.