Arquivo da categoria: Artigos

Blog de casa nova!

O blog agora tem domínio próprio: http://www.rodrigoramalho.com/, atualizem seus feeds e favoritos!

1 comentário

Arquivado em Artigos

Flex + Rails com RubyAMF

Depois de demonstrar como utilizar o dapper.net para criar um serviço XML, chegou a hora de utilizarmos o serviço criado em um aplicativo. Quero demonstrar aqui o exemplo abaixo:

Dapper gera XML a partir do Y! Finanças, que é lido pelo Flex e, via RubyAMF, salvo no BD, através do Rails. Moleza.

O Dapper gera XML a partir do Y! Finanças, que é lido pela aplicação Flex e manipulado pelo usuário. Via RubyAMF, acessamos o controller no Rails, que salva os dados no BD.

E como tudo isso funciona junto?

Já vimos como extrair os dados do Yahoo! Finanças a partir do dapper, então vamos começar descobrindo como o Flex faz para acessar este serviço. Depois explicarei um pouco sobre o backend em Rails e como é feita a integração Flex + Rails através do RubyAMF.

Flex

O nosso exemplo aberto no Flex

O nosso exemplo aberto no Flex

Ao clicarmos em Obter cotação o sistema deve acessar o serviço XML e obter o valor da ação especificada no campo Símbolo. A função getStockInfo é encarregada desta operação. Ela é chamada no evento click do botão, recebe como parâmetro o valor do campo Símbolo e faz a chamada assíncrona ao serviço XML. O parâmetro noCacheControlVar é adicionado a cada nova requisição ao serviço, para que uma nova URL seja criada e o resultado da requisição não seja cacheado no browser.

private function getStockInfo(stockCode : String) : void{
cursorManager.setBusyCursor();
var timeStampForNocache:Date = new Date() ;
var params : Object = new Object();
params.v = 1;
params.v_StockCode = stockCode;
params.noCacheControlVar = timeStampForNocache.getTime().toString();
httpStockQuoteProvider.send(params);
}

O Flex acessa serviços XML através do componente <mx:HTTPService>. Neste exemplo, vamos configurá-lo para acessar a URL http://www.dapper.net/RunDapp?dappName=Bovespa, que é a URL que contém o serviço XML que desejamos acessar.

<mx:HTTPService id="httpStockQuoteProvider" method="GET" url="http://www.dapper.net/RunDapp?dappName=Bovespa"
resultFormat="e4x"
result="httpResultHandler(event)"
fault="httpFaultHandler(event)"
showBusyCursor="true" />

O trecho de código acima nos diz muita coisa sobre o funcionamento do HTTPService. O serviço httpStockQuoteProvider irá acessar a URL informada utilizando o método GET do protocolo HTTP. O resultado – que sabemos ser em XML – será tratado pelo E4X, que é uma biblioteca de acesso nativo ao XML. Quando o serviço entrar em ação, o cursor irá mudar para uma ampulheta, pois setamos a propriedade showBusyCursor como true, e os eventos em caso de sucesso ou falha serão tratados pelas funções httpResultHandler e httpFaultHandler, respectivamente. Estas funções são responsáveis por fazer o tratamento da resposta do serviço:

private function httpResultHandler(event : ResultEvent) : void{
var dapper : XMLList = (event.result as XML).dapper;
var Quote_Details : XMLList = (event.result as XML).StockQuote;
if (dapper.status == 'OK') {
xmlStockQuoteData = Quote_Details;
txtValue.text = parseFloat(xmlStockQuoteData.Price).toString();
}else if (dapper.status == 'ERROR'){
Alert.show(dapper.description, 'Error code ' + dapper.errorCode)
}
cursorManager.removeBusyCursor();
}

A função httpResultHandler recebe o resultado do evento e popula a variável xmlStockQuoteData com os dados recebidos do XML. A variável dapper recebe os dados do nó dapper do XML e verifica o elemento status, que traz o status do serviço.

private function httpFaultHandler(event : FaultEvent) : void{
Alert.show(event.fault.message, 'HTTP Service Error');
cursorManager.removeBusyCursor();
}

A função httpFaultHandler mostra um alerta caso ocorra uma falha na conexão HTTP.

Com isso já conseguimos obter os dados do serviço XML. Mas, para tornarmos o exemplo um pouco mais prático, temos que poder manipular estes dados de alguma forma e salvá-los no banco de dados. É aí que entra o Rails, juntamente com o RubyAMF.

RubyAMF

Antes de entrar em maiores detalhes, vou explicar o que é o RubyAMF e como instalá-lo no Rails.

O RubyAMF é um gateway para comunicação entre o Flex (ou Flash) e o Rails. Ele é instalado no Rails e permite que os métodos dos controllers sejam acessados remotamente via AMF, que é um formato binário de comunicação de dados.

Instalação

O comando abaixo instala a última versão do RubyAMF.

$ script/plugin install http://rubyamf.googlecode.com/svn/current/rubyamf

Configuração

Em config/rubyamf_config.rb (que é gerado automaticamente na instalação)

ClassMappings.translate_case = true
ClassMappings.assume_types = true
ParameterMappings.scaffolding = true

translate_case: mapeia convenções de código – created_at (Rails) e createdAt (Flex).
assume_types: assume que a classe do objeto é a mesma classe remota no Flex (devem ter o mesmo nome). Pode acarretar em perda de performance quando setado como true. Pode ser substituído por ClassMappings.Register(…).
scaffolding: permite parâmetros nomeados (de params[0] para params[:stock_quote]).

Quando assume_types é false devemos utilizar ClassMappings.Register para o mapeamento entre as classes do ActionScript e do Rails:

ClassMappings.register(
:actionscript => ‘StockQuotes’,
:ruby => ‘StockQuotes’,
:type => ‘active_record’,
:attributes => [“id”, …])

Para maiores detalhes sobre estas configurações, recomendo a leitura da apresentação feita pelos criadores do RubyAMF.

Rails com RubyAMF

Scaffolding

O rubyamf_scaffold gera model, fixtures, migrations e um controller com as operações de CRUD já implementadas. Ele não gera views, pois não serão necessárias.

$ script/generate rubyamf_scaffold StockQuotes name:string value:float

Migrations

$ rake db:migrate

No Rails é só isso que precisamos fazer. Agora voltaremos ao Flex para descobrir como é feita a integração com o Rails via RubyAMF.

Flex com RubyAMF

Primeiramente, precisamos criar uma classe StockQuotes em ActionScript que reflita as propriedades da classe StockQuotes do Rails, da seguinte forma:

package
{
[RemoteClass(alias="StockQuotes")]
public class StockQuotes
{
public var id:int;
public var name:String;
public var value:Number;
public var createdAt:Date;
public var updatedAt:Date;
public function StockQuotes()
{
}
}
}

Note como marcamos a classe StockQuotes como remota com a diretiva [RemoteClass(alias="StockQuotes")]. Isto é necessário para o mapeamento de objetos remotos.

O Flex acessará o gateway criado pelo RubyAMF através do componente <mx:RemoteObject>. O RemoteObject, como o próprio nome já diz, é um componente para acesso a dados remotos. No nosso exemplo, nós o configuramos da seguinte maneira:

<mx:RemoteObject id="amfService"
destination="rubyamf"
endpoint="http://localhost:3000/rubyamf_gateway/"
source="StockQuotesController"
showBusyCursor="true"
fault="amfFaultHandler(event)" />

Veja que como endpoint nós configuramos a URL http://localhost:3000/rubyamf_gateway/, que é a URL padrao do gateway do RubyAMF. Na propriedade source setamos StockQuotesController, que é o nome do nosso controller no Rails. Desta forma o Flex conseguirá acessar os métodos deste controller para realizar as operações desejadas. A função amfFaultHandler cuidará do tratamento de erros em caso de falha na conexão.

Agora, para nos comunicarmos com o Rails via RubyAMF basta criarmos funções que façam chamadas aos métodos do controller:

private function findAll():void {
amfService.removeEventListener(ResultEvent.RESULT, saveResultHandler);
amfService.addEventListener(ResultEvent.RESULT, findAllResultHandler);
var call:AsyncToken = amfService.find_all();
}

A função findAll traz a lista de todos os dados que estão salvos no banco. Note como ela chama o método correspondente find_all do StockQuotesController. O resultado desta chamada assíncrona é tratado pela função findAllResultHandler, que mostra os dados obtidos em um grid.

Também temos funções que fazem mapeiam o Save, Update e Destroy, correspondendo à todas as funcionalidades de um CRUD simples, que é o propósito deste exemplo. Para baixar o código-fonte completo desta aplicação, acesse a sessão de downloads abaixo. Sinta-se à vontade para fazer modificações no código ou enviar sugestões e dúvidas através dos comentários.

Downloads

8 Comentários

Arquivado em Artigos

Criando serviços XML com o Dapper.net [atualizado]

O dapper.net dapper.net/open é um daqueles sites que você descobre e imediatamente quer salvar naquele cantinho dos seus favoritos onde ficam as coisas mais úteis. Imagine um aplicativo que tem por objetivo absorver conteúdo de qualquer site da internet e dá pra começar a ter uma idéia do que o dapper é. O melhor do dapper é o seu potencial de se tornar qualquer coisa que o usuário imaginar. Mas como isso é feito?

Obtendo dados do Yahoo! Finance Brasil com o Dapper

Para o meu exemplo, eu queria obter dados de cotações de ações da bovespa. Achei o Yahoo! Finance uma ótima solução, porém o serviço deles só provia dados em CSV. Eu não queria trabalhar com CSV e sim com XML, então das duas uma: ou convertia o CSV para XML ou procurava um serviço XML que me atendesse. Foi aí que eu encontrei o dapper. Com o dapper eu consegui transformar o site do Yahoo! em um serviço XML que me retorna as cotações de uma ação com base em seu símbolo.

Começando

Através da url http://br.finance.yahoo.com/q?s=VALE3.SA é possível acessar as informações das ações da Vale na Bovespa. Trocando o parâmetro s da query string podemos acessar informações de outras ações. Com essa informação em mãos podemos começar a criar um serviço com o dapper. Na página inicial é possível buscar por serviços públicos informando apenas a url de origem e o formato, ou então criar seu próprio serviço, clicando em Create a new Dapp. É isso que vamos fazer.

Criando um novo Dapp

Criando um novo Dapp

Ao clicar em Create a new Dapp você é redirecionado para a Dapp Factory, que é onde a mágica acontece. No próprio site existe um vídeo explicando como a Dapp Factory funciona, mas eu também vou dar umas dicas.

Uma visão geral da Dapper Factory

Uma visão geral da Dapper Factory

Sabemos que o conteúdo que estamos procurando está no website do Yahoo! Finance Brasil, então só o que precisamos informar é a URL http://br.finance.yahoo.com/q?s=VALE3.SA e escolhermos o formato, no caso o XML.

Clicando em Next Step o dapper nos levará a uma página de coleta de dados. Estes dados irão ajudar a ferramenta a garimpar a página informada. Então vamos criar algumas amostras mudando o parâmetro da query string, como http://br.finance.yahoo.com/q?s=PETR4.SA e http://br.finance.yahoo.com/q?s=BBAS3.SA. Vá mudando os parâmetros da URL, clique em GO para acessar a página e finalmente em Add To Basket. Quando tiver três ou mais amostras, pode clicar em Next Step, para o dapper analisá-las.

Coletando as amostras

Coletando as amostras da VALE3.SA, PETR4.SA e BBAS3.SA

Depois de o dapper ter analisado as amostras, é hora de escolher os campos que farão parte do serviço, ou seja, quais são os dados que o dapper irá garimpar desta página para criar o seu serviço XML.

Escolhendo os campos

Escolhendo os campos

Escolha o campo e clique em Save Field para salvá-lo. O dapper pede que você dê um nome a ele e, futuramente, este nome será usado para criar o elemento correspondente no XML. Você pode criar campos com um ou mais elementos. Neste exemplo eu vou criei os campos NomeAcao e ValorAcao.

Criação dos campos NomeAcao e ValorAcao

Criação dos campos NomeAcao e ValorAcao

Clicando em Next Step vemos um preview do conteúdo extraído da página e podemos criar agrupamentos. Veja que eu criei o agrupamento Acao, contendo os campos NomeAcao e ValorAcao. Este agrupamento se tornará um nó no XML gerado pelo dapper.

Agrupando os campos

Agrupando os campos

Agora falta pouco. Ao salvarmos o dapper temos que prestar atenção no campo InputVariables, que é o campo que nos permite criar variáveis para o serviço. Os trechos da URL que irão mudar devem ser transformados em variáveis. No exemplo, eu removo o símbolo VALE3.SA (que é o símbolo das ações da Vale do Rio Doce) e crio a variável {SimboloAcao}, uma variável genérica que muda conforme a ação que desejamos consultar. É importante lembrar que as variáveis devem estar entre chaves.

Finalizando o serviço

Finalizando o serviço

Após salvar seu serviço, o dapper abrirá uma página de configuração, onde você poderá editar seu dapper e até mesmo utilizá-lo, pois ele já estará funcionando. O legal desta parte é que você pode alterar o formato do resultado em Choose Format.

Seu novo serviço está pronto para ser utilizado

Seu novo serviço está pronto para ser utilizado

Escolhendo XML e clicando em GO o dapper mostra o serviço em formato XML e a URL de acesso do mesmo, no nosso caso http://www.dapper.net/RunDapp?dappName=AcoesBovespaXML&v=1&v_SimboloAcao=PETR4.SA, onde a variável v_SimboloAcao pode ser alterada para qualquer outro símbolo que desejarmos consultar.

Dapper em XML

Dapper em XML - note a URL do serviço

Para você obter o XML deste serviço, basta acessar http://www.dapper.net/RunDapp?dappName=AcoesBovespaXML&v=1&v_SimboloAcao=PETR4.SA (troque PETR4.SA por qualquer outro símbolo da Bovespa que queira consultar).

Agora fica fácil integrar este serviço XML com qualquer frontend que precise manipulá-lo, como uma aplicação em Flex por exemplo.

[UPDATE] O dapper mudou de endereço, agora é http://www.dapper.net/open/.

4 Comentários

Arquivado em Artigos

Princípios de Design de Interface Gráfica – Parte 4/4

E chegamos ao final do artigo sobre princípios de design. Na primeira parte discutimos o usuário, na segunda os testes de usabilidade e na terceira os princípios e boas práticas de design. Nesta parte final eu vou falo um pouco sobre usabilidade e acessibilidade.

Parte 4 – Usabilidade e acessibilidade

Imagine o seguinte cenário: ao desenvolver um novo software, você analisa os requisitos de usabilidade baseando-se em um determinado público alvo, que geralmente é um conjunto de pessoas com boa visão, audição e também boas funções motoras. Com a lista de requisitos pronta para esta audiência, você começa a fazer o design do seu sistema, tentando garantir uma boa experiência aos usuários. Com tempo e esforço o design vai evoluindo, até atingir um ponto em que todos estejam satisfeitos. Finalmente o sistema atende aos requisitos do público alvo!

O cenário acima é comum na maioria das empresas de desenvolvimento de software. Mas e se pensarmos que um sistema deve atender não somente ao público alvo inicial, mas também a outros públicos, como pessoas com problemas de visão, audição ou de funções motoras? Neste caso, como o sistema irá se comportar? Será que estes usuários terão uma experiência tão boa usando o sistema quanto os usuários do primeiro cenário?

É aí que entra a acessibilidade. Não existe um botão mágico que torna um sistema que foi desenhado com uma audiência em mente acessível a diversas outras audiências. E hoje em dia, em muitas empresas de desenvolvimento de software estas audiências costumam ser ignoradas. Como podemos garantir uma boa experiência de usuário para estas pessoas, que não fazem parte da “audiência padrão”?

Neste caso, podemos pensar em acessibilidade como usabilidade para audiências diferenciadas. Todas as regras de usabilidade se aplicam, porém tendo em mente um novo público alvo. Não é possível ter uma aplicação realmente acessível para usuários com requisitos especiais sem fazer um design tendo estes usuários em mente. Assim atingimos a acessibilidade através da usabilidade.

Atingir a acessibilidade através da usabilidade significa que você precisa analisar os requisitos para usuários especiais da mesma maneira que você analisa para todos os outros usuários. Você deve fazer testes de usabilidade com estes usuários e, principalmente, deve perceber que o termo “usuários especiais” se refere a diversas audiências, com diferentes requisitos como problemas de visão, audição e motores. E claro, isto terá custos. Porém, se você tem preocupações sérias quanto à experiência de seus usuários, estes custos são importantes e necessários.

Para saber mais

Assim concluímos esta série de artigos sobre princípios de design. Se você tem dúvidas, sugestões ou mesmo reclamações, deixe seu comentário abaixo ou entre em contato.

3 Comentários

Arquivado em Artigos, Usabilidade

Princípios de Design de Interface Gráfica – Parte 3/4

Este post é o terceiro de uma série de posts sobre princípios de design de interface gráfica. No primeiro post discutimos a importância do usuário e no segundo falamos sobre testes de usabilidade. Confira-os!

Antes de começar a falar sobre os princípios de design, devo lembrar a vocês que estes princípios não servem para substituir os testes de usabilidade e sim para guiar o desenvolvimento da interface gráfica de uma aplicação, antes que ela seja apresentada aos usuários. Com isso em mente, vamos à eles:

Parte 3 – Os princípios de design

1. Vocabulário

É importante que seja definido um vocabulário próprio para uma aplicação. Cada elemento de uma aplicação deve ser definido por apenas um termo ou frase, não importando em quais telas este elemento aparece. Isto é necessário para evitar problemas de comunicação entre os membros da equipe e também diminuir o risco de confundir o usuário.

2. Diminuir o esforço do usuário

A ergonomia de sua aplicação também é importante. Devemos lembrar que os usuários utilizam nossas aplicações por muitas horas durante o dia e, por vezes, fazendo um trabalho repetitivo. A LER é um problema que pode ocorrer a muitas pessoas, e toda ação que evite o esforço desnecessário do usuário deve ser tomada, pois, como desenvolvedores, temos a nossa parcela de responsabilidade. Algumas ações que podem ser tomadas são:

  • Agrupar campos semelhantes dentro de uma mesma tela.
  • Usar atalhos de teclado, evitando que o usuário tenha que acessar o mouse.
  • Usar preenchimentos pré-definidos para campos e auto-complete sempre que possível.

3. Tenha iniciativa: tome decisões

O trabalho de um designer de interfaces também inclui a tomada de decisões sobre como os campos vão ser organizados. Não basta apenas jogar os campos na tela e esperar a resposta do usuário. Telas com grande quantidade de campos geralmente são indicadores de problemas de design. Neste caso uma revisão é sempre bem-vinda. Não espere o usuário reclamar, faça antes e evite o retrabalho!

4. Deixe o usuário trabalhar

O usuário deve ser capaz de fazer suas tarefas mais freqüentes – e importantes – sem interferências. Evite usar validações e mensagens de aviso no estilo pop-up, pois são extremamente invasivas e acabam tirando a concentração do usuário. Sempre que possível, substitua as mensagens em pop-up por mensagens mais discretas, como textos destacados, por exemplo. Isto nos leva ao próximo princípio:

5. Previna, não avise

Projete sua aplicação pensando em prevenir que o usuário cometa erros, ao invés de projetar pensando em avisar após ele cometer erros.

6. Não deixe o usuário perdido

Projete suas interfaces para dar respostas às ações do usuário. O usuário nunca deve ter que pensar “Isso funcionou?” quando estiver usando sua aplicação. Este princípio também se aplica ao controle do fluxo de sua aplicação. Projete menus e telas de forma que o usuário não fique perdido dentro do sistema. Use breadcrumbs ou outra forma de dica para que o usuário sempre saiba onde está e não tenha que pensar “Como cheguei aqui?”.

7. Use dicas visuais

Já ouviu dizer que uma imagem vale mais do que mil palavras? Se você pode representar algo com uma imagem ao invés de um texto, faça-o. No máximo use uma legenda curta para explicar a imagem. É muito mais fácil para o usuário aprender a usar o seu sistema através de imagens do que de longos textos explicativos.

8. Não venda o que você não pode entregar

Se o usuário tem uma expectativa sobre a sua aplicação, desenvolva seu sistema de modo que essa expectativa seja cumprida. Caso contrário, seu usuário ficará decepcionado com o sistema logo no início. O grande problema disso é que uma decepção inicial pode gerar uma insatisfação crônica entre os usuários – e o sistema nunca conseguirá conquistá-los totalmente.

9. Performance

Não deixe os usuários esperando. Sua aplicação deve ser rápida o suficiente dado o contexto em que ela se aplica. No caso de períodos de espera prolongados, use dicas visuais para informar ao usuário que um processamento está ocorrendo, como barras de progresso e mudança do cursor do mouse para uma ampulheta, por exemplo.

10. Validação

O usuário deve ser avisado sobre um erro de validação em um controle apenas se ele interagiu com esse controle de alguma forma. Não mostre um formulário cheio de erros e depois remova-os conforme o usuário o preenche. Espere o usuário interagir com o formulário de alguma forma, para depois mostrar as mensagens de validação.

Para saber mais

1 comentário

Arquivado em Artigos, Usabilidade

Princípios de Design de Interface Gráfica – Parte 2/4

Na parte 1 deste artigo eu falei sobre a importância de se ouvir o usuário quando estamos desenvolvendo um sistema. Uma forma muito eficiente de se fazer isto é realizando testes de usabilidade, que é o assunto deste post.

Parte 2 – Testes de usabilidade

“Os testes de usabilidade devem ser uma atividade iterativa durante o ciclo de vida de um projeto. O resultado disso é um produdo final melhorado e um melhor entendimento do ponto de vista dos usuários do sistema” (Joshua Kaufman, em Practical Usability Testing).

Ou seja: teste uma vez, teste sempre e depois teste de novo. O objetivo de um teste de usabilidade é aprender como o usuário pensa e o que ele espera do sistema.

Conduzir um teste deste tipo não é algo muito complicado, porém requer boa vontade e disponibilidade de tempo e recursos. A receita é simples:

São necessários

  • Duas salas
  • Um ou mais usuários
  • Um computador rodando a sua aplicação
  • Uma pessoa para conduzir o teste de usabilidade
  • Uma filmadora
  • Uma TV

O computador deve ficar em uma sala e a TV em outra. A filmadora deve ser ajustada para filmar a tela do computador e transmitir para a TV. Na sala com o computador, o usuário deverá realizar uma série de ações propostas pelo condutor do teste. Na sala de TV a equipe de desenvolvedores deverá assistir ao teste de usabilidade.

Uma outra opção é gravar as ações do usuário com um software de captura de tela, como o Camtasia. O Camtasia pode gravar áudio e vídeo, que depois podem ser transmitidos para os desenvolvedores.

O teste deve ser feito com um usuário e depois repetido com os demais. Recomenda-se um número mínimo de 5 e um número máximo de 20 usuários.

É papel do condutor do teste de usabilidade explicar ao usuário e cenário e os objetivos do teste. O condutor deve indicar ao usuário por onde começar e pedir a ele que durante o teste “pense em voz alta”. Isto é importante para que todos entendam o que o usuário está pensando ao realizar uma ação.

Durante o teste é importante que o usuário fique livre para realizar as ações. O condutor deve interrompê-lo o mínimo possível, evitando ensinar o “caminho das pedras”.

Também é interessante que se tenha um questionário para que, ao final do teste, o usuário deixe as suas opiniões.

E claro, deve-se sempre planejar muito bem o teste, definindo objetivos, cenários e questionários previamente, para que o teste seja aproveitado ao máximo.

Para saber mais

2 Comentários

Arquivado em Artigos, Usabilidade

Princípios de Design de Interface Gráfica – Parte 1/4

Este texto é uma tradução/adaptação do artigo User Interface Design Principles for Web Applications, de Aral Balkan. Apesar de o artigo tratar de princípios de design para aplicações web, muitos destes princípios podem ser aplicados de maneira semelhante no desenvolvimento de aplicações desktop.

Parte 1 – O usuário

  1. O cliente não é o usuário
    Os clientes muitas vezes têm a certeza de que sabem exatamente quais são as necessidades dos usuários finais do sistema. Mas não é sempre que isto ocorre, simplesmente porque o cliente – na grande maioria dos casos – não é o usuário final, portanto, como ele pode saber exatamente o que o usuário final quer?
  2. Não dê ao cliente o que ele pensa que o usuário final quer
    Uma aplicação deve atender às necessidades do usuário final. Tendo em vista que o cliente não sabe o que o usuário quer, quando tentamos atender somente ao cliente podemos estar criando uma base não muito sólida para a nossa aplicação se desenvolver. Ou seja, o cliente pode estar feliz inicialmente, mas com o tempo os problemas começarão a aparecer, usuários irão reclamar para o cliente, e ele começará a pedir mudanças no sistema.
    Concluindo: Quando estivermos projetando uma aplicação, devemos ouvir o usuário, descobrir quais os problemas que ele tem e como podemos resolvê-los.
  3. Você não sabe o quê o seu usuário deseja
    Simplesmente porque a cada nova aplicação que desenvolvemos, os usuários mudam, e consequentemente, as suas necessidades também mudam. Então quem sabe o que os usuários querem?
  4. Somente os usuários sabem o que eles querem
    Este é um conceito tão básico que muitas vezes é esquecido pelos desenvolvedores de software. Somente os usuários de uma aplicação sabem o que funciona bem e o que não funciona. Devemos ouví-los sempre.

Para saber mais

4 Comentários

Arquivado em Artigos, Usabilidade