<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.caelum.com.br</title>
	<atom:link href="http://blog.caelum.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Tue, 15 May 2012 12:49:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>JavaCE Conference 2012 &#8211; Eu Fui</title>
		<link>http://blog.caelum.com.br/javace-conference-2012-eu-fui/</link>
		<comments>http://blog.caelum.com.br/javace-conference-2012-eu-fui/#comments</comments>
		<pubDate>Tue, 15 May 2012 12:49:18 +0000</pubDate>
		<dc:creator>Raphael Lacerda</dc:creator>
				<category><![CDATA[Caelum]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[cejug]]></category>
		<category><![CDATA[comunidade]]></category>
		<category><![CDATA[conferencia]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[fortaleza]]></category>
		<category><![CDATA[javace]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=5050</guid>
		<description><![CDATA[Nos dias 11 e 12 de maio aconteceu, em Fortaleza, o JavaCE Conference, evento com foco na plataforma Java e não restrito apenas a ela. Foram abordadas outras linguagens como C#, Ruby e Scala, além do desenvolvimento mobile para Android e iOS. O evento foi organizado pela Milfont Consulting e TriadWorks. No primeiro dia, Paulo <a href="http://blog.caelum.com.br/javace-conference-2012-eu-fui/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/javace.png" width="240" />
		</p><p>Nos dias 11 e 12 de maio aconteceu, em Fortaleza, o <a href="http://conference.javace.org/">JavaCE Conference</a>, evento com foco na  plataforma Java e não restrito apenas a ela. Foram abordadas outras linguagens como C#, Ruby e Scala, além do desenvolvimento mobile para Android e iOS. O evento foi organizado pela <a href="http://www.milfont.org/">Milfont Consulting</a> e <a href="http://triadworks.com.br/">TriadWorks</a>. </p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/javace.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/javace-214x300.png" alt="" title="javace" width="214" height="300" class="aligncenter size-medium wp-image-5051" /></a></p>
<p>No primeiro dia, Paulo Silveira e eu apresentamos a principal novidade do futuro próximo do Java, o projeto <a href="http://openjdk.java.net/projects/lambda/">Lambda do JDK 8</a>, passando por APIs que trazem uma programação mais funcional em Java, como o <a href="blog.caelum.com.br/codigo-expressivo-e-programacao-funcional-em-java-com-lambdaj">LambdaJ</a>. Loiane Groner mostrou como ser produtivo com VRaptor e ExtJS, além de fazer uma introdução aos dois frameworks. A equipe TriadWorks analisou várias ferramentas de build (ant, maven e gradle), mostrando vantagens e desvantagens para depois apresentar features do poder do Groovy com Gradle. Carlos Villela e Gregório Melo, da ThoughtWorks, trataram sobre NoSQL, mostrando features do Redis e do HBase, assim como um pouco do <a href="http://blog.caelum.com.br/nosql-do-teorema-cap-para-paccl/">teorema CAP</a>. Otavio Santana também apresentou casos de uso sobre bancos NoSQL, focando o Apache Cassandra e no Java.</p>
<p>Ainda teve Douglas Campos fazendo uma palestra hardcore sobre o invoke dynamic, a nova instrução do bytecode do Java 7. Diogo Souza que fez uma excelente e divertida apresentação sobre <a href="http://blog.caelum.com.br/injecao-de-dependencias-no-android-com-roboguice/">RoboGuice, ferramenta para injeção de dependências para aplicações Android</a>. Ele explicou desde os conceitos básicos de Injeção dependência até demonstração de código e ainda salientou sobre <a href="http://blog.caelum.com.br/2012-e-o-ano-do-mercado-mobile-no-brasil/">o ano mobile no país</a>. E por fim tivemos Leonardo Leitão falando sobre Rest e Cloud Computing, e Bruno Souza finalizou com uma discussão sobre os rumos da plataforma Java, o caso da Oracle X Google e como a comunidade e os desenvolvedores se enquadram em toda essa situação. O Tiago Ribeiro também <a href="http://tiagoribeirof.blogspot.com.br/2012/05/java-ce-community-conference-o-que.html">postou sobre o primeiro dia do evento</a>.</p>
<p>No segundo dia, Alberto Souza explicou as facilidades e dificuldades encontradas no desenvolvimento de uma aplicação em Scala, cuidados em relação ao uso dos implicits e o problema do tooling, compilador e do sbt: todos incipientes. Tivemos Marlus Saraiva com JasperReports no Ruby on Rails. Luca Bastos fez uma palestra divertida sobre machine learning, mostrando que ela está presente em praticamente todas as ferramentas que utilizamos. Maurício Linhares fez uma palestra sobre  algumas dificuldades que ele teve com Ruby, Java e que com Scala foram sanadas. Por fim, Rodrigo Kumpera explicou da dificuldade dos desenvolvedores mobile em ter que programar cross-plataform, haja visto que cada plataforma (iOS, Android, Windows) utiliza uma linguagem diferente. Ele apresentou a proposta do Mono que é uniformizar C# como linguagem de desenvolvimento para as três ambientes. Ainda tivemos palestras sobre integração contínua com Tiago Bastos e big data analytics com Fernando Meyer.</p>
<p>Foi um evento que mais uma vez mostrou a força que tem a comunidade Java, que há tempos saltou de focar na linguagem para abordar mais firmemente a plataforma e até outras tecnologias. Sem falar na destacada comunidade cearense, sempre presente em eventos de todo o Brasil. Quem foi pode ver muitos dos tópicos quentes sendo apresentados, sem contar as produtivas conversas nos corredores e até mesmo codificação durante os vários happy hours. Tudo isso em uma ensolarada Fortaleza. Nos vemos nos próximos eventos, como o <a href="http://www.conexaojava.com.br/">Conexão Java</a>, focado no público iniciante da plataforma, e no <a href="http://www.qconsp.com/">QCon SP</a>, uma conferência para os desenvolvedores mais experientes. Fica o agradecimento a todos organizadores, especialmente  ao Christiano Milfont,  pela coordenação e confiança.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/javace-conference-2012-eu-fui/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Trabalhando com JSON no iOS</title>
		<link>http://blog.caelum.com.br/trabalhando-com-json-no-ios/</link>
		<comments>http://blog.caelum.com.br/trabalhando-com-json-no-ios/#comments</comments>
		<pubDate>Thu, 10 May 2012 13:07:12 +0000</pubDate>
		<dc:creator>Diego Chohfi</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ip-67]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[objectivec]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=5022</guid>
		<description><![CDATA[Com o crescimento do mercado mobile, a integração de sistemas com os pequenos aparelhos se tornou essencial. O formato JSON se popularizou com a mesma velocidade que o desenvolvimento mobile. Sua simplicidade e facilidade de desenvolver parsers o tornou uma das principais alternativas na integração de sistemas web, em especial para ser consumido via AJAX. <a href="http://blog.caelum.com.br/trabalhando-com-json-no-ios/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/json-ios.png" width="240" />
		</p><p>Com o crescimento do mercado mobile, a integração de sistemas com os pequenos aparelhos se tornou essencial. O formato <a href="http://www.json.org" title="JSON">JSON</a> se popularizou com a mesma velocidade que o desenvolvimento mobile. Sua simplicidade e facilidade de desenvolver parsers o tornou uma das principais alternativas na integração de sistemas web, em especial para ser consumido via AJAX.</p>
<p>No <strong>iOS</strong> não foi diferente. A necessidade dos desenvolvedores levou o surgimento de diversas bibliotecas que faziam o trabalho de ler e gerar JSON com extrema facilidade, como o <a href="https://github.com/stig/json-framework/" title="JSON-Framework">JSON Framework</a> e o <a href="https://github.com/TouchCode/TouchJSON" title="TouchJSON">TouchJSON</a>. Porém a Apple não quis ficar de fora e incorporou a classe <a href="http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html" title="NSJSONSerialization"><code>NSJSONSerialization</code></a>, capaz de gerenciar o formato tanto no iOS como no desenvolvimento para OSX, com a mesma facilidade que as bibliotecas opensource trouxeram.</p>
<p>Recetemente <a href="https://github.com/caelum/onibus-ios">desenvolvemos um projeto para iOS</a> para auxiliar os alunos do <a href="http://www.caelum.com.br/curso/ip-67-desenvolvimento-movel-ios-5-iphone-ipad/" title="IP-67">nosso curso de iOS, o IP-67</a>, enriquecendo a experiência e trazendo um exemplo bem palpável. A aplicação consiste em buscar os pontos de ônibus próximos a localização do usuário. Para integrar a nossa aplicação com um backend em Ruby utilizamos JSON como o formato e a classe <code>NSJSONSerialization</code> se mostrou extremamente simples e fácil de se trabalhar. Vamos entender como fizemos, do lado do dispositivo, a leitura e manipulação dos dados.</p>
<p>Primeiramente precisamos obter as informações no formato JSON para então parsea-los. Utilizando o método <code>+ (id)dataWithContentsOfURL:(NSURL *)url;</code> da classe <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html" title="NSData">NSData</a> para fazer uma request e obter as informações de forma síncrona em um endereço da WEB:</p>
<pre class="brush: objc; title: ; notranslate">
NSString *url = [NSString stringWithFormat:@&quot;http://ondeestaoalbi.herokuapp.com/onibusesNosPontosProximos.json?lat=%f&amp;long=%f&quot;, -23.588453, -46.632103];
NSData *jsonData = [NSData dataWithContentsOfURL: [NSURL URLWithString:url]];
</pre>
<p>O nosso serviço retornará um JSON com a seguinte estrutura:</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;nome&quot;: &quot;920016054&quot;,
    &quot;descricao&quot;: &quot;R. Dr. Neto De Araujo, 311&quot;,
    &quot;coordenada&quot;: {
        &quot;latitude&quot;: -23.5876,
        &quot;longitude&quot;: -46.6321
    }
}
</pre>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/json-ios.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/json-ios.png" alt="" title="json-ios" width="393" height="309" class="aligncenter size-full wp-image-5041" /></a></p>
<p>Após receber as informações, vamos utilizar a classe <code>NSJSONSerialization</code> para transformar o JSON em um <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsdictionary_Class/Reference/Reference.html" title="NSDictionary" >NSDictionary</a>, contendo as chaves e valores das informações sobre o ponto.</p>
<pre class="brush: objc; title: ; notranslate">
NSError* error;
NSDictionary *resultados = [NSJSONSerialization JSONObjectWithData:jsonData
                options:NSJSONReadingMutableContainers error:&amp;error];
</pre>
<p>Caso o JSON seja válido e a conversão seja feita com sucesso podemos buscar os valores no <code>NSDictionary</code> a partir de uma chave, utilizando o método <code>- (id)objectForKey:(id)aKey;</code>:</p>
<pre class="brush: objc; title: ; notranslate">
NSError *error;
NSDictionary *resultados = [NSJSONSerialization JSONObjectWithData:jsonData
                options:NSJSONReadingMutableContainers error:&amp;error];
if(!error) {
    NSString *nome = [resultados objectForKey:@&quot;nome&quot;];
    NSString *descricao = [resultados objectForKey:@&quot;descricao&quot;];
    NSLog(@&quot;Nome: %@, descrição: %@&quot;, nome, descricao);
}
</pre>
<p>Poderíamos continuar utilizando o <code>NSDictionary</code> para armazenar as informações dos pontos encontrados, mas imagine que por algum motivo precisemos mostrar a descrição do nosso Ponto sempre com letra minúscula e removendo os espaços do começo e do fim da nossa NSString, o código ficaria da seguinte forma:</p>
<pre class="brush: objc; title: ; notranslate">
    NSString *nome = [resultados objectForKey:@&quot;nome&quot;];
    NSString *descricao = [[resultados objectForKey:@&quot;descricao&quot;] lowercaseString];
    descricao = [descricao stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSLog(@&quot;Nome: %@, descrição: %@&quot;, nome, descricao);
</pre>
<p>Perceba que o código não é mais tão simples quanto anteriormente, além disso, precisaríamos espalhá-lo por todo o projeto. A manutenção também seria difícil, pois precisaremos <em>copiar e colar</em> o mesmo código toda vez que a descrição for exibida e caso a regra de exibição seja alterada o código que copiamos e colamos terá que ser alterado.</p>
<p>Temos esse problema pois estamos utilizando a classe <code>NSDictionary</code> para guardar <strong>estado</strong> do nosso <code>Ponto</code> e não podemos definir nenhum comportamento adicional. Para manter os dados organizados e de fácil manutenção devemos sempre criar classes para representar tipos e não mantê-los na representação de chave e valor, desta forma, além de guardar o estado do objeto, podemos também definir novos comportamentos, facilitando a manutenção e a reutilização de código.</p>
<p>Vamos criar as classes com os referentes atributos e também definir um método de classe para criar uma instância do <code>Ponto</code>, esse método será responsável por buscar suas informações em um <code>NSDictionary</code> passado como argumento. Essa regra fica isolada e fácil de dar manutenção caso alguma das chaves mude:</p>
<pre class="brush: objc; title: ; notranslate">
#import &lt;Foundation/Foundation.h&gt;
#import &quot;Coordenada.h&quot;

@interface Ponto : NSObject

@property(nonatomic, strong) NSString *nome;
@property(nonatomic, strong) NSString *descricao;
@property(nonatomic, strong) Coordenada *coordenada;

+ (Ponto *) comDicionario: (NSDictionary *) dicionario;

@end

#import &quot;Ponto.h&quot;

@implementation Ponto
@synthesize nome, descricao, coordenada;

+ (Ponto *) comDicionario: (NSDictionary *) dicionario {
	Ponto * ponto = [[Ponto alloc] init];
	[ponto setNome: [dicionario objectForKey:@&quot;nome&quot;]];
	[ponto setDescricao: [dicionario objectForKey:@&quot;descricao&quot;]];

	Coordenada *coordenada  = [Coordenada comDicionario: [dicionario objectForKey: @&quot;coordenada&quot;]];
	[ponto setCoordenada: coordenada];
	return ponto;
}

@end
</pre>
<p>Se fosse preciso definir uma regra para buscar a descrição do <code>Ponto</code> da forma que descrevemos anteriormente, podemos alterar o método que busca o atributo na classe, isolando o código e facilitando futuras manutenções.</p>
<pre class="brush: objc; title: ; notranslate">
#import &quot;Ponto.h&quot;

@implementation Ponto
@synthesize nome, descricao, coordenada;

- (NSString *) descricao {
    NSString *descricaoEmMinusculo = [descricao lowercaseString];
    return [descricaoEmMinusculo stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

@end
</pre>
<p>Para obter um Ponto a partir de um JSON chegamos ao seguinte código:</p>
<pre class="brush: objc; title: ; notranslate">
NSString *url = [NSString stringWithFormat:@&quot;http://ondeestaoalbi.herokuapp.com/onibusesNosPontosProximos.json?lat=%f&amp;long=%f&quot;, -23.588453, -46.632103];
NSData *jsonData = [NSData dataWithContentsOfURL: [NSURL URLWithString:url]];

NSError *error;
NSDictionary *resultados = [NSJSONSerialization JSONObjectWithData:jsonData
                options:NSJSONReadingMutableContainers error:&amp;error];
if(!error){
    Ponto *ponto = [Ponto comDicionario: resultados];
    NSLog(@&quot;Ponto: %@&quot;, ponto.descricao);
}
</pre>
<p>Percebendo a dificuldade e a duplicação de código que temos que escrever ao buscar os valores no <code>NSDictionary</code>, desenvolvemos uma pequena biblioteca para facilitar essa tarefa. O <code><a href="https://github.com/dchohfi/KeyValueObjectMapping">KeyValueObjectMapping</a></code> surgiu da necessidade de transformar grandes estruturas de dados automaticamente em objetos, seguindo padrões e quando necessário adicionando configurações para alterar as convenções. Poderíamos remover a implementação do método <code>+ (Ponto *) comDicionario: (NSDictionary *) dicionario;</code> e com o <code>KeyValueObjectMapping</code> teríamos:</p>
<pre class="brush: objc; title: ; notranslate">
DCKeyValueObjectMapping *parser = [DCKeyValueObjectMapping mapperForClass:[Ponto class]];
Ponto *ponto = [parser parseDictionary:resultados];
</pre>
<p>Lembrando que o <code>KeyValueObjectMapping</code> serve para transformar qualquer tipo de dado que se comporte como um <code>NSDictionary</code>, chave e valor, podendo ser um JSON, um PLIST, entre outros. Você está convidado a contribuir nos projetos!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/trabalhando-com-json-no-ios/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>As múltiplas personalidades do this em JavaScript</title>
		<link>http://blog.caelum.com.br/as-multiplas-personalidades-do-this-em-javascript/</link>
		<comments>http://blog.caelum.com.br/as-multiplas-personalidades-do-this-em-javascript/#comments</comments>
		<pubDate>Mon, 07 May 2012 14:18:12 +0000</pubDate>
		<dc:creator>Ricardo Valeriano</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[this]]></category>
		<category><![CDATA[wd-47]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=5032</guid>
		<description><![CDATA[Se você já escreveu algum código JavaScript, não deve mais achar estranho quando alguém atribui uma função a uma variável. Mas o que exatamente acontece quando você faz isso? Em JavaScript, as funções podem ser passadas como parâmetros para outras funções, retornadas como valor e, como já dito, referenciadas por variáveis. A linguagem trata as <a href="http://blog.caelum.com.br/as-multiplas-personalidades-do-this-em-javascript/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/12/javascript.jpg" width="240" />
		</p><p>Se você já escreveu algum código JavaScript, não deve mais achar estranho quando alguém atribui uma função a uma variável. Mas o que exatamente acontece quando você faz isso? Em JavaScript, as funções podem ser passadas como parâmetros para outras funções, retornadas como valor e, como já dito, referenciadas por variáveis. A linguagem trata as funções como <a href="http://en.wikipedia.org/wiki/First-class_function">cidadãs de primeira classe</a>.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/12/javascript.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/12/javascript-300x225.jpg" alt="" title="javascript" width="300" height="225" class="aligncenter size-medium wp-image-5035" /></a></p>
<p>O JavaScript representa funções como objetos. Quando atribuímos uma função a uma variável, estamos criando uma referência para um objeto do tipo <code>function</code>. Podemos ver isso de forma clara utilizando o operador <code>typeof</code>. O exemplo abaixo cria uma função e a atribui a variável chamada <code>apresentar</code>, que recebe como parâmetro um objeto com os atributos <em>nome</em> e <em>email</em>. Vamos invocar a função e a seguir usar o operador <code>typeof</code> para inspecionar o tipo que é referenciado pela variável usada para guardar a função:</p>
<pre class="brush: jscript; title: ; notranslate">
var apresentar = function(pessoa) {
     console.log(&quot;Eu sou &quot;+ pessoa.nome +&quot; e meu email é: &quot;+ pessoa.email);
}

apresentar({nome: &quot;Ricardo&quot;, email: &quot;ricardo.valeriano@caelum.com.br&quot;});
// Eu sou Ricardo e meu email é: ricardo.valeriano@caelum.com.br

typeof(apresentar); // &quot;function&quot;
</pre>
<p>Quando invocamos uma função com o operador <code>()</code>, estamos utilizando uma forma de invocação chamada por alguns de <a href="https://developer.mozilla.org/en/JavaScript/Reference/Operators/this#Simple_call">invocação simples</a>. O maneira como uma função é invocada tem efeito direto sobre como a palavra chave <code>this</code> é &#8220;atribuída&#8221; no corpo da função.</p>
<p>Quando seu código JavaScript é executado em um navegador, uma variável global chamada <code>window</code> é criada para representar a própria janela do navegador. E quando a forma simples de invocação é usada, o objeto referenciado por <code>this</code> é equivalente ao <code>window</code>, veja:</p>
<pre class="brush: jscript; title: ; notranslate">
typeof(window); // &quot;object&quot;

console.log(window); // DOWWindow

var verificandoWindow = function() {
    console.log(this);
    console.log(this === window);
}
verificandoWindow();
// DOWWindow, true
</pre>
<p>Notou que o tipo referenciado por <code>window</code> é <code>object</code>? Podemos criar nossa própria instância de <code>object</code> usando a chamada <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Object_literals">notação literal</a>, que é a que foi usada para criar o parametro passado na invocação da função <code>apresentar</code> no nosso primeiro exemplo.</p>
<p>A variável <code>window</code> é uma referência para um objeto e podemos adicionar atributos a ele! Quando criamos uma variável fora de uma função (ou seja no escopo
<li>global</li>
<p>), automaticamente um atributo com o mesmo nome da variável é criado em <code>window</code> para referenciar o objeto atribuído a nova variável. Quando tentamos acessar o valor dessas variáveis, estamos, na verdade, recuperando o valor de um atributo de <code>window</code>. Veja o exemplo a seguir:</p>
<pre class="brush: jscript; title: ; notranslate">
var todosPodemMeVer = &quot;porque sou um atributo de window&quot;;
console.log(window.todosPodemMeVer);
// porque sou um atributo de window

var pessoa = {
   nome:  &quot;Ricardo&quot;,
   email: &quot;ricardo.valeriano@caelum.com.br&quot;
}

console.log(pessoa.nome);
// Ricardo

console.log(window.pessoa === pessoa);
// true
</pre>
<p>Toda função tem acesso à palavra chave <code>this</code>. Vamos usar isso para obter informações sobre esse objeto. Vamos criar as propriedades <em>nome</em> e <em>email</em> em <code>window</code> e alterar a função para buscar os valores usando atributos presentes em <code>this</code>, e não mais do objeto recebido como argumento:</p>
<pre class="brush: jscript; title: ; notranslate">
var nome = &quot;João da Silva&quot;;
window.email = &quot;joao@da.silva&quot;;

var apresentar = function() {
    console.log(this === window);
    console.log(&quot;Eu sou &quot;+ this.nome +&quot; e meu email é &quot;+ this.email);
}

apresentar();
// true
// Eu sou João da Silva e meu email é joao@da.silva
</pre>
<p>Veja que criamos um atributo novo chamado <code>email</code> para o objeto referenciado por <code>window</code>. Um atributo pode referenciar qualquer objeto, inclusive funções. Para ilustrar, vamos criar um novo atributo chamado <code>quemSouEu</code> em <code>pessoa</code>, que é uma referência para a função <code>apresentar</code> do exemplo anterior. Dessa forma, será possível invocar essa função diretamente a partir do objeto <code>pessoa</code>.</p>
<pre class="brush: jscript; title: ; notranslate">
var pessoa = {
   nome:  &quot;Ricardo&quot;,
   email: &quot;ricardo.valeriano@caelum.com.br&quot;
}
</pre>
<p>Mas a função usa internamente a variável <code>this</code> para fazer seu trabalho, certo? Será que isso vai continuar funcionando? Repare a saída:</p>
<pre class="brush: jscript; title: ; notranslate">
pessoa.quemSouEu = apresentar;
pessoa.quemSouEu();
// false
// Eu sou Ricardo e meu email é ricardo.valeriano@caelum.com.br

apresentar();// Agora novamente invocando a função com o operador ()
// true
// Eu sou João da Silva e meu email é joao@da.silva
</pre>
<p>Uma função referenciada por um atributo de um objeto pode ser invocada como um método daquele objeto, a palavra chave <code>this</code> é atribuída ao objeto onde a função foi invocada.</p>
<p>Uma outra forma de executar uma função no contexto de um objeto específico é invocando o método <code>call</code> disponível em todo objeto do tipo <code>function</code>. Esse método possibilita definir o objeto referenciado por <code>this</code> no momento da invocação:</p>
<pre class="brush: jscript; title: ; notranslate">
apresentar.call(pessoa);
// false
// Eu sou Ricardo e meu email é ricardo.valeriano@caelum.com.br
</pre>
<p>Mas não pense que acabou! Existem ainda outras formas de invocar funções que interferem em como a palavra <code>this</code> é atribuída. Por exemplo, o operador <code>new</code> pode ser utilizado em associação com o operador <code>()</code> para invocar qualquer função, isso vai fazer com que o <code>this</code> seja atribuído a um novo objeto. O retorno da função também pode ser alterado por essa forma de invocação. Você lerá sobre esses detalhes na segunda parte desse artigo.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/as-multiplas-personalidades-do-this-em-javascript/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Injeção de dependências no ASP.NET MVC</title>
		<link>http://blog.caelum.com.br/injecao-de-dependencias-no-asp-net-mvc/</link>
		<comments>http://blog.caelum.com.br/injecao-de-dependencias-no-asp-net-mvc/#comments</comments>
		<pubDate>Thu, 03 May 2012 13:05:24 +0000</pubDate>
		<dc:creator>Victor Kendy Harada</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[Inovação]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[online]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4995</guid>
		<description><![CDATA[Para melhorar a manutenibilidade de um sistema, devemos programar voltados para interface. Assim, nos preocupamos apenas com o contrato definido pela interface, não com sua implementação, diminuindo o acoplamento do código. Uma das formas de facilitar essa prática é utilizar a injeção de dependências. Dessa forma, nossas classes não precisam conhecer a lógica de instanciação, <a href="http://blog.caelum.com.br/injecao-de-dependencias-no-asp-net-mvc/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/aspnet.gif" width="240" />
		</p><p>Para melhorar a manutenibilidade de um sistema, <a href="http://stackoverflow.com/questions/1257670/c-sharp-when-to-program-to-an-interface">devemos</a> <a href="http://www.arquiteturajava.com.br/livro/programe-voltado-a-interface-nao-a-implementacao.pdf">programar voltados para interface</a>. Assim, nos preocupamos apenas com o contrato definido pela interface, não com sua implementação, diminuindo o acoplamento do código. Uma das formas de facilitar essa prática é utilizar a injeção de dependências. Dessa forma, nossas classes não precisam conhecer a lógica de instanciação, ciclo devida e nem implementação dos componente do sistema, podendo mudar facilmente a implementação de suas dependências.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/aspnet.gif"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/05/aspnet-300x232.gif" alt="" title="aspnet" width="300" height="232" class="aligncenter size-medium wp-image-5026" /></a></p>
<p>Quando escrevemos um controller no <a href="http://www.caelum.com.br/curso/online/aspnetmvc/">ASP.NET MVC</a>, é interessante que a classe não precise se preocupar com a instanciação de suas dependências.  Queremos, por exemplo, receber todas essas dependências no construtor. Vamos usar como exemplo um <code>UserController</code> que precisa de um <code>IUserDao</code>:</p>
<pre class="brush: java; title: ; notranslate">
class UserController {
  private IUserDao userDao;
  public UserController(IUserDao userDao) {
      this.userDao = userDao;
  }
}
</pre>
<p>Porém, o ASP.NET MVC não consegue instanciar um controller escrito dessa forma. Ele não sabe como instanciar um <code>IUserDao</code>! Por esse motivo, apenas controllers que tenham um construtor sem argumentos podem ser instanciados. Para mudar esse comportamento, precisamos ensinar o ASP.NET MVC a instanciar controladores que recebem parâmetros no construtor.</p>
<h2>Unity Container</h2>
<p>Para que possamos criar instâncias de classes que recebam as dependências pelo construtor, precisamos primeiro guardar as instâncias dessas dependências em algum lugar. Precisamos, por exemplo, ter um <code>IUserDao</code> em mãos para passar para o construtor do <code>UserController</code>.</p>
<p>Existem diversos frameworks que nos ajudam nessa tarefa. Eles são conhecidos como frameworks de injeção de dependência. Nesse post utilizaremos o framework de injeção de dependências da Microsoft, o <strong><a href="http://unity.codeplex.com/">Unity</a></strong>.</p>
<p>O Unity nos oferece uma classe chamada <code>UnityContainer</code>, classe na qual podemos registrar tipos que serão injetados. Para registrar uma dependência, utilizamos o método <code>RegisterType</code> do container, passando a interface, a implementação que deve ser injetada e um nome para ela.</p>
<p>No exemplo, queremos registrar o <code>UserController</code> como uma implementação de <code>IController</code> e o <code>UserDao</code> como uma implementação de <code>IUserDao</code>. Além disso, para seguir a convenção de nomes do ASP.NET MVC, registraremos o <code>UserController</code> com o nome <em>User</em>.</p>
<pre class="brush: java; title: ; notranslate">
Container.RegisterType(typeof(IUserDao), typeof(UserDao));
Container.RegisterType(typeof(IController), typeof(UserController), “User”);
</pre>
<p>Agora que temos registrado no Unity tanto o Dao quanto o Controller, podemos pedir instâncias dessas classes para ele! Ao pedirmos uma instância de <code>UserController</code>, o Unity se encarregará de enviar o <code>UserDao</code> para o construtor dele:</p>
<pre class="brush: java; title: ; notranslate">
IController controller = Container.Resolve&lt;IController&gt;(&quot;User&quot;);
</pre>
<h2>ControllerFactory com Injeção de Dependências</h2>
<p>Agora precisamos ensinar o ASP.NET MVC a utilizar o Unity para instanciar os controllers. Para fazer isso, precisamos criar uma classe que implementa <code>IControllerFactory</code>. Implementações dessa interface devem fornecer três métodos: <code>CreateController</code>, <code>ReleaseController</code> e <code>GetControllerSessionBehavior</code>.</p>
<p><code>CreateController</code> recebe uma <code>String</code> com o nome do controller que precisa ser criado e deve devolver uma instância de <code>IController</code>. <code>ReleaseController</code> recebe um <code>IController</code> e deve liberar os recursos utilizados. A <code>String</code> com o nome do controller segue <a href="http://msdn.microsoft.com/en-us/gg618491">a convenção do ASP.NET MVC</a>, ou seja, quando recebemos a <code>String</code> &#8220;<em>User</em>&#8220;, devemos criar uma instância de <code>UserController</code>.</p>
<pre class="brush: java; title: ; notranslate">
class UnityFactory : IControllerFactory {
  public UnityFactory() {
    this.Container = new UnityContainer();
    this.Container.RegisterType(typeof(IUserDao), typeof(UserDao));
    this.Container.RegisterType(typeof(IController), typeof(UserController), “User”);
  }

  public IController CreateController (RequestContext context, String controllerName) {
    IController controller = this.Container.Resolve&lt;IController&gt;(controllerName);
    return controller;
  }
  // ...
}
</pre>
<p>Precisamos também ensinar o ASP.NET MVC a destruir nosso controller e liberar quaisquer recursos que alocamos. Para isso, vamos implementar o método <code>ReleaseController</code>:</p>
<pre class="brush: java; title: ; notranslate">
public void ReleaseController(IController controller) {
  this.Container.Teardown(controller);
}
</pre>
<p>O <code>GetControllerSessionBehavior</code> deve retornar o valor de um enum que define o comportamento da session do ASP.NET MVC. Como queremos que a Session tenha <a href="http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatebehavior.aspx">o mesmo comportamento da Session padrão</a>, esse método vai retornar <code>System.Web.SessionState.SessionStateBehavior.Default</code>.</p>
<pre class="brush: java; title: ; notranslate">
public System.Web.SessionState.SessionStateBehavior
      GetControllerSessionBehavior(RequestContext ctx, string controllerName) {
  return System.Web.SessionState.SessionStateBehavior.Default;
}
</pre>
<p>Estamos quase lá. Resta apenas substituir o mecanismo padrão do ASP.NET MVC pelo que acabamos de criar. Essa substituição é feita no arquivo <code>Global.asax</code> do projeto, através do método <code>SetControllerFactory</code>. Para manter a organização do arquivo <code>Global.asax</code>, o registro do <code>ControllerFactory</code> ficará junto com as configurações globais dentro do método <code>Application_Start()</code>:</p>
<pre class="brush: java; title: ; notranslate">
protected void Application_Start() {
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);
  UnityFactory factory = new UnityFactory();
  ControllerBuilder.Current.SetControllerFactory(factory);
}
</pre>
<p>Agora que a aplicação está utilizando a fábrica customizada, o ASP.NET MVC é capaz de instanciar o <code>UserController</code>, passando o <code>UserDao</code> para ele! Essa factory ainda pode ser melhorada. Poderíamos, por exemplo, registrar automaticamente no Unity todos os controllers e componentes que serão injetados. Você pode ver essa implementação, um pouco mais complicada, <a title="Implementação da Unity Factory" href="https://gist.github.com/2490266">aqui</a>. Além disso, você pode ver a implementação da factory utilizando o container <a href="http://docs.castleproject.org/Windsor.MainPage.ashx">Windsor</a> no projeto <a href="https://github.com/caelum/agile-tickets-csharp">agile-tickets-csharp</a>, projeto utilizado no curso <a href="http://msdn.microsoft.com/en-us/gg618491">PM-87</a> da Caelum.</p>
<p>Pronto! Nossos controllers agora podem declarar suas dependências no construtor, deixando o código mais claro e mais fácil de ser testado. Aprenda a desenvolver com ASP.NET MVC em nosso <a title="Curso Online de ASP.NET MVC" href="http://www.caelum.com.br/curso/online/aspnetmvc/">curso online</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/injecao-de-dependencias-no-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Scala Days Londres 2012: como foi o evento</title>
		<link>http://blog.caelum.com.br/scala-days-londres-2012-como-foi-o-evento/</link>
		<comments>http://blog.caelum.com.br/scala-days-londres-2012-como-foi-o-evento/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 13:08:43 +0000</pubDate>
		<dc:creator>Alberto Souza</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[funcional]]></category>
		<category><![CDATA[linguagens]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[scala days]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=5007</guid>
		<description><![CDATA[Entre os dias 17 e 18 de abril aconteceu em Londres o Scala Days, evento que reuniu diversos ícones envolvidos com o desenvolvimento da linguagem Scala, a qual também já foi tema de diversos posts no blog da Caelum. A grade contou com palestras sobre frameworks utilizados no mundo de desenvolvimento do Scala, detalhes de <a href="http://blog.caelum.com.br/scala-days-londres-2012-como-foi-o-evento/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays.jpg" width="240" />
		</p><p>Entre os dias 17 e 18 de abril aconteceu em Londres o <a href="http://days2012.scala-lang.org/">Scala Days</a>, evento que reuniu diversos ícones envolvidos com o desenvolvimento da linguagem <a href="http://blog.caelum.com.br/scala-sua-proxima-linguagem/">Scala</a>, a qual também já foi tema de diversos posts no blog da Caelum. <a href="http://days2012.scala-lang.org/program">A grade contou com palestras</a> sobre frameworks utilizados no mundo de desenvolvimento do Scala, detalhes de implementação do compilador, estado das IDE&#8217;s que estão sendo desenvolvidas para melhorar o ferramental, até casos de uso da linguagem nas empresas.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays.jpg"><img class="aligncenter size-medium wp-image-5020" title="scaladays" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays-300x180.jpg" alt="scala days london 2012" width="300" height="180" /></a></p>
<p>Um detalhe bastante interessante foi ver a preocupação com os problemas de tempo de compilação e <a href="http://lift.la/scalas-version-fragility-make-the-enterprise">compatibilidade binária</a> que a linguagem apresenta. Ainda é muito comum que as versões novas de bibliotecas não sejam compativeis com versões prévias e versões novas da linguagem obrigarem os mantenedores dos frameworks a recompilarem seus projetos. O <a href="http://www.scalatest.org/download">ScalaTest</a>, por exemplo, tem versões de downloads para diferentes versões do Scala.</p>
<p>O keynote mais esperado foi o de Martin Odersky, principal criador da linguagem, comentando sobre os rumos do Scala. Ele comentou sobre as novas <a href="http://docs.scala-lang.org/sips/index.html">SIP&#8217;s</a>, Scala Improvement Process, que são as propostas de melhorias para a linguagem, algo análogo às JSRs. Três bastante comentadas foram as <a href="http://docs.scala-lang.org/sips/pending/implicit-classes.html">Implicit Classes</a>, <a href="http://docs.scala-lang.org/sips/pending/value-classes.html">Values Classes</a> e as <a href="http://docs.scala-lang.org/sips/pending/self-cleaning-macros.html">Macros</a>. Esta última é uma nova maneira de realizar meta-programação na linguagem, a ideia é tranformar as Macros na forma padrão de criar extensões do compilador. Martin também comentou sobre a nova <a href="http://alots.wordpress.com/2012/03/06/getting-into-the-new-scalas-2-10-reflection-api/">API de reflection</a> que foi introduzida na versão 2.10 da linguagem. Eles conseguiram facilitar bastante a vida do programdor, principalmente quando é necessário analisar detalhes específicos do código Scala, como os implicits.</p>
<p><center><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays10.jpg"><img title="scaladays10" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays10-150x150.jpg" alt="" width="150" height="150" /></a> <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays3.jpg"><img title="scaladays3" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays3-150x150.jpg" alt="" width="150" height="150" /></a> <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays1.jpg"><img title="scaladays1" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/scaladays1-150x150.jpg" alt="" width="150" height="150" /></a></center>&nbsp;</p>
<p>Foi um evento muito bom, enquanto que no ano passado tiveram em torno de 250 inscrições, esse ano chegou na marca de 400 pessoas. Ficou claro que os próximos passos da linguagem são na direção de deixá-la mais preparada para uma abordagem enterprise. O esforço na melhoria das IDEs, compatibilidade binária e compilador deixa evidente a preocupação do time da Typesafe com o ferramental de suporte. O mesmo ferramental que é alvo de muitas critícas hoje em dia. Um outro ponto importante é a importância dada à inovação: basta analisar as novas SIP&#8217;s que trazem sempre novidades. Você já pode conferir <a href="http://skillsmatter.com/event/scala/scala-days-2012">algumas das palestras online</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/scala-days-londres-2012-como-foi-o-evento/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Integração contínua de projeto Java com Jenkins</title>
		<link>http://blog.caelum.com.br/integracao-continua-de-projeto-java-com-jenkins/</link>
		<comments>http://blog.caelum.com.br/integracao-continua-de-projeto-java-com-jenkins/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 12:54:38 +0000</pubDate>
		<dc:creator>Francisco Sokol</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[integração]]></category>
		<category><![CDATA[integração contínua]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[pm-87]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4923</guid>
		<description><![CDATA[Há bastante tempo aplicamos e escrevemos sobre integração contínua, uma das práticas mais importantes do desenvolvimento ágil. Através dela, é possível agilizar tarefas demoradas como a compilação de um projeto e a execução dos seus testes automatizados. Com um servidor de integração contínua bem configurado, essas tarefas são executadas a cada mudança no repositório de código e, em caso de <a href="http://blog.caelum.com.br/integracao-continua-de-projeto-java-com-jenkins/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/config.png" width="240" />
		</p><p>Há bastante tempo <a href="http://blog.caelum.com.br/integracao-continua/">aplicamos e escrevemos sobre integração contínua</a>, uma das práticas mais importantes do desenvolvimento ágil. Através dela, é possível agilizar tarefas demoradas como a compilação de um projeto e a execução dos seus testes automatizados. <strong>Com um servidor de integração contínua bem configurado, essas tarefas são executadas a cada mudança no repositório de código e, em caso de erros de compilação ou falhas nos testes automatizados, todos os desenvolvedores são alertados rapidamente</strong>. Dessa forma, se o servidor de integração não aponta problemas no projeto, a equipe tem a segurança de que as mudanças no código estão de acordo com a bateria de testes. É também um passo na direção do <a href="http://blog.caelum.com.br/o-processo-de-deploy-continuo/">deploy contínuo</a>.</p>
<p>Nesse post, iremos ensinar como instalar e configurar um projeto simples com testes de unidade no <a href="http://jenkins-ci.org/">Jenkins</a>, uma versão renovada (e forkada) do Hudson, o servidor de integração contínua que utilizamos aqui na Caelum e um dos mais populares.</p>
<p>O Jenkins é distribuído como um war e portanto pode ser deployado em um servidor de aplicação como o Tomcat ou o Jetty. Nesse post, iremos utilizar o Tomcat e vamos supor que ele já esteja instalado no seu computador. Chamaremos a home do Tomcat de &lt;tomcat&gt;. Você também deve ter o ant instalado no seu computador pois o utilizaremos para compilar o código e executar os testes. Baixe a <a href="http://mirrors.jenkins-ci.org/war/latest/">versão mais recente do Jenkins</a> e coloque no diretório <code>&lt;tomcat&gt;/webpps/</code>. Inicie o servidor de aplicação executando o script <code>&lt;tomcat&gt;/bin/startup.sh</code>. Depois disso, você poderá acessar a interface web do jenkins pela URL <code>http://localhost:8080/jenkins/</code> no seu navegador.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/screen.png"><img class="aligncenter size-full wp-image-4991" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/screen.png" alt="" width="549" height="363" /></a></p>
<p>Para demonstrar a configuração de um projeto novo, iremos utilizar um <a href="https://github.com/csokol/jenkins-exemplo">projeto simples</a>, criado para esse tutorial. Ele possui apenas duas classes bem simples e uma classe de teste com o JUnit. Além disso, o projeto possui um <code>build.xml</code> configurado para compilar o  projeto, executar os testes e gerar um jar. Você pode também ir aplicando todos os passos em seu próprio projeto. Se você ainda não desenvolve com integração contínua, vai poder mudar bastante a forma com que sua equipe desenvolve e receber um feedback contínuo do que está acontecendo.</p>
<p>Como o projeto se encontra em um repositório Git, será necessário instalar um plugin do Git no Jenkins (inicialmente, o Jenkins só suporta CVS e SVN). Para isso, vá até o plugin manager do Jenkins (<em>Manage Jenkins &gt; Manage Plugins</em>) na aba <em>Avaiable</em>, habilite o <em>Git Plugin</em> e clique em <em>Download now and install after restart</em> (pode ser que não exista nenhum plugin disponível na aba <em>Avaiable</em>, nesse caso, vá até a aba <em>Advanced</em> e clique em <em>Check Now</em> para atualizar o repositório de plugins). Depois do término da instalação do plugin, você deverá reiniciar o Jenkins.</p>
<p>Com o plugin instalado, podemos criar uma nova task no Jenkins para compilar e executar os testes do nosso projeto. Clique em <em>New Job</em>, dê um nome a ele, selecione a opção <em>Build a free-style software project</em> e clique em Ok. Você será redirecionado para a página de configurações do projeto.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/config.png"><img class="aligncenter size-full wp-image-4992" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/config.png" alt="" width="549" height="352" /></a></p>
<p>Na seção Source Code Management, selecione Git e coloque a url pública do repositório (<code>git://github.com/csokol/jenkins-exemplo.git</code>). Em <em>Build Triggers</em>, selecione <code>Poll SCM</code> e no campo <code>Schedule</code> coloque &#8220;<code>*/5 * * * *</code>&#8220;. Essa configuração determina que o Jenkins irá verificar se houve alterações no repositório desde o último build a cada cinco minutos. Se existir alguma, irá atualizar o seu repositório e executar o job.</p>
<p style="text-align: center"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/1-cut1.png"><img class="aligncenter size-full wp-image-4984" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/1-cut1.png" alt="" width="550" height="453" /></a></p>
<p>Nesse projeto temos duas targets principais do ant que queremos executar no Jenkins, uma para executar os testes e outra para gerar um jar do projeto, pronto para ser distribuído. Para configurar a execução dessas targets, selecione a opção <em>Invoke Ant</em> na seção <em>Build</em> e no campo <em>Targets</em> coloque <code>test jar</code>, essas são as targets que executa os testes e gera o jar, respectivamente.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/2-cut2.png"><img class="aligncenter size-full wp-image-4990" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/2-cut2.png" alt="" width="550" height="109" /></a></p>
<p>Agora, precisamos configurar as ações que o Jenkins irá executar depois de executar o ant. Caso exista alguma falha nos testes ou na criação do jar, o Jenkins deve notificar a equipe, para isso, na seção <em>Post-build Actions</em> selecione <em>E-mail Notification</em> e adicione os emails que devem ser notificados em caso de falha no build. Além disso, gostaríamos também de guardar o jar gereado pelo ant, para isso, selecione <em>Archive the artifacts</em> e coloque <code>target/*.jar</code> no campo <em>Files to archive</em>. Assim, toda vez que o job for executado, o Jenkins irá disponibilizar o jar para download em sua interface. Clique em <em>Save</em> para salvar as configurações.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/3-cut.png"><img class="aligncenter size-full wp-image-4986" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/3-cut.png" alt="" width="550" height="311" /></a></p>
<p>Pronto! Agora o projeto está configurado e cada alteração no repositório irá disparar o Job no Jenkins, executando os testes de unidade:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/4-cut.png"><img class="aligncenter size-full wp-image-4987" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/4-cut.png" alt="" width="550" height="258" /></a></p>
<p>Como nesse momento o Job nunca foi executado, o primeiro irá iniciar automaticamente e você poderá vizualizá-lo no painel do lado esquerdo em <em>Build history</em>. Você também pode inicar o processo manualmente, clicando em <em>Build Now</em>. Com o build finalizado, você pode visualizar sua página de status, onde poderá baixar o jar criado e também examinar o resultado dos testes em <em>Console Output</em>.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/5-cut.png"><img class="aligncenter size-full wp-image-4988" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/5-cut.png" alt="" width="550" height="248" /></a></p>
<p>O Jenkins oferece muitos outros recursos além dos descritos aqui, ele é capaz de executar diversas tarefas, como colocar deployar um war em um servidor em produção, gerar relatórios de cobertura de testes, calcular métricas sobre o código do projeto, entre outras. Você poderá conhecer essas funcionalidades explorando os plugins disponíveis ou mesmo desenvolvendo o seu.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/integracao-continua-de-projeto-java-com-jenkins/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>2012 é o ano do mercado mobile no Brasil</title>
		<link>http://blog.caelum.com.br/2012-e-o-ano-do-mercado-mobile-no-brasil/</link>
		<comments>http://blog.caelum.com.br/2012-e-o-ano-do-mercado-mobile-no-brasil/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 13:15:15 +0000</pubDate>
		<dc:creator>Sérgio Lopes</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[fj-57]]></category>
		<category><![CDATA[ip-67]]></category>
		<category><![CDATA[mercado]]></category>
		<category><![CDATA[wd-43]]></category>
		<category><![CDATA[wd-47]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4830</guid>
		<description><![CDATA[O mercado mobile está explodindo em todo o mundo, e no Brasil não é diferente. Saiba porque e como aproveitar as oportunidades. É verdade que o Brasil já ultrapassou a marca de mais celulares que gente há algum tempo. Ainda em 2010, batemos a marca de 200 milhões de linhas. Desde então, o volume de <a href="http://blog.caelum.com.br/2012-e-o-ano-do-mercado-mobile-no-brasil/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/brasil.jpg" width="240" />
		</p><p><em>O mercado mobile está explodindo em todo o mundo, e no Brasil não é diferente. Saiba porque e como aproveitar as oportunidades.</em></p>
<p>É verdade que o Brasil já ultrapassou a marca de <b>mais celulares que gente</b> há algum tempo. Ainda em 2010, batemos a marca de <a href="http://www.brasil.gov.br/noticias/arquivos/2011/01/19/brasil-ultrapassa-marca-de-200-milhoes-de-celulares">200 milhões de linhas</a>. Desde então, o volume de linhas não pára de crescer, a ponto de já termos o <a href="http://tecnologia.uol.com.br/ultimas-noticias/redacao/2012/01/27/numeros-de-celular-terao-nove-digitos-em-sp-a-partir-de-julho-diz-anatel.jhtm">nono dígito</a> nos números celulares de SP a partir de Julho.</p>
<p>É verdade também que já desenvolvemos aplicativos para celulares há muitos anos. Só aqui na Caelum, oferecemos cursos de <a href="http://www.caelum.com.br/curso/fj-55-java-me-mobile/">Java ME</a> desde <b>2005</b> e <a href="http://www.caelum.com.br/curso/fj-57-desenvolvimento-google-android/">Android</a> desde <b>2010</b>. Livros sobre desenvolvimento para celulares são bestsellers em todas as livrarias nacionais já faz tempo.</p>
<p>Apesar de tudo isso, eu acredito que <strong>2012 será um ano particular para o mercado móvel no Brasil</strong>. Muita coisa está acontecendo agora nessa área. E o potencial é gigantesco.</p>
<p><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/introduction-300x266.png" alt="" title="Google Nexus" width="300" height="266" class="aligncenter size-medium wp-image-4835" /></p>
<h3>Consumidores + &#8230;</h3>
<p>Uma <a href="http://www.slideshare.net/WMcCannBR/consumidor-mvel-2011">pesquisa antiga</a> &#8211; de fevereiro de 2011 &#8211; mostrava que <B>33% das pessoas já tinham smartphone</B> e 20% tinha celular convencional avançado (com Wifi, GPS etc). <b>41% acessava a Internet</b> no celular (83% entre os donos de smartphone!). 15% já tinha efetuado alguma compra via celular (63% entre usuários de iPhone!). Mais da metade das pessoas tinha um celular com menos de 6 meses de uso. E 40% das pessoas pretendia trocar de aparelho nos seis meses seguintes.</p>
<p>Recentemente, saiu a informação de que <a href="http://g1.globo.com/tecnologia/noticia/2012/03/vendas-de-smartphones-no-brasil-crescem-179-em-2011-diz-pesquisa.html">a venda de smartphones cresceu 179%</a> em 2011 no Brasil. Muita gente ainda compra celulares convencionais, mas o <b>preço médio do smartphone caiu 33%</b> em 2011, facilitando a maior adoção. A <a href="http://imagens.extra.com.br/html/infografico/celular-no-brasil.html">banda larga móvel cresce assustadoramente</a> e já ultrapassou a banda larga fixa há algum tempo.</p>
<p>O pessoal do <a href="http://analytics.blogspot.com/2012/01/look-ahead-at-measurement-in-2012.html">Google Analytics divulgou</a> que, só nos últimos 4 meses de 2011, <B>o número de usuários mobile cresceu 40%</B>. Mais: vem crescendo <b>2% por semana</b> e eles prevêem um boom para 2012.</p>
<p>E, apenas para colocar os números em perspectiva: por dia, <b>370 mil</b> novos seres humanos nascem no mundo todo. E, por dia, só de aparelhos Androids são novos <b>700 mil</b>. E ainda temos mais <B>380 mil</B> iPhones/dia. Se somar todos os smartphones e tablets, são <b>1 milhão e meio</b> de novos aparelhos por dia, uma taxa de crescimento <b>4x maior que a da população mundial</b>.</p>
<p><a href="http://www.lukew.com/ff/entry.asp?1506"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/whymobile-3.png" alt="" title="Bebes vs iPhones e Androids" width="500" height="324" class="aligncenter size-full wp-image-4902" /></a></p>
<h3>&#8230; + Governo</h3>
<p>As novidades para 2012 atingem até políticas governamentais. Foram anunciados <strong>incentivos fiscais</strong> tanto para produção de <a href="http://info.abril.com.br/noticias/mercado/dilma-sanciona-incentivo-fiscal-para-tablets-11102011-50.shl">tablets</a> quanto de <a href="http://www.techtudo.com.br/noticias/noticia/2012/02/smartphones-ficarao-mais-baratos-com-incentivo-fiscal-afirma-ministro-paulo-bernardo.html">smartphones</a> no Brasil. O iPhone 4 já é produzido no Brasil desde o ano passado e o iPad começou esse ano. </p>
<p>A tendência é que o preço dos aparelhos caia bastante ainda esse ano e que surjam smartphones a preços populares.</p>
<h3>&#8230; + Aparelhos</h3>
<p>Pela primeira vez, o Google trouxe para o Brasil um modelo da sua <a href="http://www.google.com.br/nexus/">grife Nexus</a> de celulares de ponta. É o primeiro modelo com <b>Android 4.0</b> a chegar por aqui. Aliás, essa que é a versão do Android mais revolucionária lançada até hoje e que logo estará em diversos aparelhos novos e em updates para aparelhos já existentes.</p>
<p>No mundo Apple, cada novo lançamento quebra novamente recordes anteriores. A Microsoft e a Nokia lançam sua linha <b>Lumia com Windows Phone</b> no Brasil com bastante barulho.</p>
<p>E não é só de celulares e tablets que vive o mundo móvel. A <a href="http://www.publishnews.com.br/telas/noticias/detalhes.aspx?id=67049">chegada iminente da Amazon ao Brasil</a> vai trazer uma revolução à parte no mundo dos ebooks e do comércio eletrônico. E, junto, vem o <strong>Kindle</strong> para a preços arrasadores. Inclusive o <strong>Kindle Fire</strong>, seu tablet barato com Android que conseguiu deixar o mercado americano de tablets de ponta cabeça no final do ano passado.</p>
<p><img alt="" src="https://images-na.ssl-images-amazon.com/images/G/01/reading/images/logo_kindle2._V167628491_.png" title="Amazon Kindle" class="aligncenter" width="186" height="44" /></p>
<h3>&#8230; + Novos comportamentos</h3>
<p>O Google recentemente divulgou diversas <a href="http://www.thinkwithgoogle.com/insights/uploads/194364.pdf">estatísticas sobre a última edição do Super Bowl americano</a> e o efeito nas buscas. Uma em particular me chamou a atenção: <b>25% de todas as buscas realizadas sobre o Super Bowl foram feitas em dispositivos móveis</b>.</p>
<p>Mais: durante o jogo, provavelmente com a TV ligada, <b>41% das buscas foram feitas em dispositivos móveis</b>.</p>
<p><a href="http://www.thinkwithgoogle.com/insights/uploads/194364.pdf"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/Screen-Shot-2012-02-13-at-8.14.54-PM-e1329171387828.png" alt="" title="Estatísticas do Super Bowl de 2012" width="500" height="264" class="aligncenter size-full wp-image-4834" /></a></p>
<p>Nas compras não é diferente. O pessoal do <a href="http://googlemobileads.blogspot.com/2011/12/look-back-at-2011.html">Google Adwords fez uma pesquisa</a> que mostrou que <b>79% dos consumidores usam o celular no processo de compra</b> &#8211; seja comparando preços, analisando opções etc. Mais: <b>70% da pessoas usam o celular quando estão <u>dentro</u> da loja física</b>.</p>
<p>É uma imensa mudança de comportamento! </p>
<p>Usamos celulares a todo momento, e frequentemente para <em>complementar</em> uma experiência já existente. Juntamos mídias ao usar nosso dispositivo enquanto vemos TV e mudamos toda a lógica do comércio ao usar o celular para uma compra física mais informada.</p>
<p>O <a href="http://www.paypal.com">PayPal</a>, especializado em pagamentos online, teve <em>141 milhões de dólares</em> movimentados em transações via mobile em 2009. Esse número cresceu para <em>750 milhões de dólares</em> em 2010 e para incríveis <b><a href="http://www.businessweek.com/news/2012-01-11/ebay-s-paypal-mobile-payment-volume-rose-to-4-billion-last-year.html">4 bilhões de dólares</a></b> em 2011!</p>
<p>O Facebook, maior rede social do Brasil e do mundo, teve <b><a href="http://www.webperformancetoday.com/2012/02/23/mobile-web-performance-unlimited-data/">33% de todo o seu tráfego</a></b> de 2011 originado em dispositivos móveis. No Twitter, incríveis <b>55% do tráfego</b> foram em mobile em 2011.</p>
<h3>= Tremendas oportunidades</h3>
<p>O mercado móvel está só no começo, <b>sobretudo no Brasil</b>.</p>
<p>Aquela <a href="http://www.slideshare.net/WMcCannBR/consumidor-mvel-2011">pesquisa de 2011</a> sobre o consumidor móvel brasileiro, mostrava ainda que mais de 50% das pessoas <b>desejavam que houvesse mais conteúdo móvel disponível</b>. E <b>65% mostraram intenção de comprar um tablet</b>.</p>
<p>Um <a href="http://www.gomez.com/wp-content/downloads/19986_WhatMobileUsersWant_Wp.pdf">estudo da Gomez em Julho de 2011</a>, mostrou a gritante diferença entre as expectativas dos usuários mobile e a (ainda) triste realidade. <b>71% das pessoas esperam que um site móvel seja tão rápido quanto no Desktop</b> mas para 46% a experiência foi de mais lentidão. E <b>57% das pessoas falaram ter tido problemas ao acessar sites em seus celulares</b>.</p>
<p>São muitas oportunidades!</p>
<p>Para o Google, os imensos avanços de 2011 são apenas o começo da história do mundo móvel. E, <a href="http://googlemobileads.blogspot.com/2011/12/look-back-at-2011.html">eles falam também que 2012 será o grande ano de mobile</a>.</p>
<h2>Como atacar o mercado móvel?</h2>
<p>Há basicamente dois caminhos: <B>criar uma app mobile</B> e <b>criar um site mobile</b>.</p>
<h3>Apps</h3>
<p><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/overview_hero.jpg" alt="" title="Apps de iPhone" width="500" height="142" class="aligncenter size-full wp-image-4836" /></p>
<p>Apps dão uma excelente experiência para o usuário, por serem nativas e se integrarem muito bem com o aparelho. Existe a inconveniência da portabilidade &#8211; e mesmo você fazendo uma para iOS e outra para Android, não esqueça que existem zilhões de outros usuários (e 70% deles nem smartphone têm).</p>
<p>Jacok Nielsen, o papa da usabilidade, <a href="http://www.useit.com/alertbox/mobile-sites-apps.html">afirma que Apps dedicadas hoje provêem uma melhor experiência pro usuário</a>. São mais integradas ao aparelho e conseguem minimizar as limitações com maior sucesso.</p>
<p>Mas talvez o ponto mais crítico para Apps seja o mais óbvio: <i>elas precisam ser instaladas</i>. Apps são ótimas para quem já é seu cliente, mas são uma <b>barreira para converter novos clientes</b>. Ninguém quer instalar uma nova App para cada empresa e serviço do mundo.</p>
<p>Aqui entra a <b>Web mobile</b>, uma área que eu particularmente vejo com muito potencial de crescimento. </p>
<p>E a conclusão daquele <a href="http://www.useit.com/alertbox/mobile-sites-apps.html">artigo</a> do Jakob Nielsen sobre Apps serem melhores de UX hoje, é que a <b>Web Mobile é bem melhor</b> a longo a prazo e será a <b>solução definitiva</b> conforme os navegadores móveis forem evoluindo.</p>
<h3>Web mobile</h3>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/tudo.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/tudo-e1329171044862.jpg" alt="" title="10 telas diferentes abrindo o site do livro de arquitetura da Caelum" width="500" height="232" class="aligncenter size-full wp-image-4833" /></a></p>
<p>Muita gente acessa a Internet no celular e a maioria navegando por aí. E é péssimo abrir algum Site que não esteja otimizado para mobile. Mesmo nos smartphones mais modernos com telas maiores que permitem abrir sites normais, não há dúvidas que <B>um site não otimizado para mobile traz uma pior experiência para o usuário</B>. E isso prejudica suas vendas, trata mal potenciais clientes e até afeta negativamente sua marca.</p>
<p>Se quiser tirar uma lição desse post gigante e transformá-la em uma ação para esse ano, faça isso: <b>crie <u>já</u> uma versão mobile do seu site</b>.</p>
<p>E não é só para grandes portais ou redes sociais. É fato que as pessoas lêem muitas notícias em seus celulares e tablets, mas também lêem blogs e outros conteúdos. Também querem fazer compras online enquanto estiverem na rua. E querem receber um link qualquer por email ou Facebook e poder visualizá-lo no seu dispositivo. Querem apenas&#8230; <i>navegar normalmente</i>.</p>
<p><b>Todos os sites deveriam funcionar bem em dispositivos móveis.</b></p>
<p>Aqui você pode estar pensando no trabalho de criar uma versão nova do seu site para mobile. E que talvez não valha muito a pena o investimento, dado o (ainda) pequeno número de usuários. Mas você pode apenas adaptar seu site normal para todo tipo de dispositivo, como mostro nesse <a href="http://sergiolopes.org/responsive-web-design/">artigo sobre design resposivo</a>.</p>
<p>Fizemos isso no site do <a href="http://www.arquiteturajava.com.br">Livro de Arquitetura Java da Caelum</a> <b>sem muito esforço</b>. O chato é saber que, após ler sobre o livro em seu dispositivo, o usuário terá uma péssima experiência tentando comprá-lo caso não esteja em seu Desktop, já que as lojas virtuais brasileiras <em>não estão prontas para o mundo móvel</em>.</p>
<p>Mas é disso que trata esse post: <b>despertar para a explosão do mundo mobile</b> e <b>incentivar que cada um faça sua parte</b> para mudarmos o cenários mobile no Brasil.</p>
<p>E se você precisar de uma ajuda pra fazer Apps móveis, a Caelum têm cursos para <a href="http://www.caelum.com.br/curso/fj-57-desenvolvimento-google-android/">Android</a> e <a href="http://www.caelum.com.br/curso/ip-67-desenvolvimento-movel-ios-5-iphone-ipad/">iOS</a>. E nosso <a href="http://www.caelum.com.br/curso/wd-43-desenvolvimento-web-html-css-javascript/">curso de desenvolvimento Web</a> trata também de sites mobile.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2012-e-o-ano-do-mercado-mobile-no-brasil/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Gerenciamento de memória e o ARC no Objective-C</title>
		<link>http://blog.caelum.com.br/gerenciamento-de-memoria-e-o-arc-no-objective-c/</link>
		<comments>http://blog.caelum.com.br/gerenciamento-de-memoria-e-o-arc-no-objective-c/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 13:20:34 +0000</pubDate>
		<dc:creator>Ricardo Valeriano</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ip-67]]></category>
		<category><![CDATA[memória]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[objectivec]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4822</guid>
		<description><![CDATA[Em outubro de 2011 a Apple lançou o iOS 5. Os desenvolvedores comemoraram bastante a disponibilização de uma funcionalidade chamada Automatic Reference Couting (ARC), que promete facilitar muito o desenvolvimento de aplicações iOS. O desenvolvedor Objective-C precisa se  preocupar com o gerenciamento de memória em suas aplicações, basicamente isso significa alocar a memória que será <a href="http://blog.caelum.com.br/gerenciamento-de-memoria-e-o-arc-no-objective-c/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/memory_management.jpg" width="240" />
		</p><p>Em outubro de 2011 a Apple lançou o iOS 5. Os desenvolvedores comemoraram bastante a disponibilização de uma funcionalidade chamada <a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html">Automatic Reference Couting</a> (ARC), que promete facilitar muito o desenvolvimento de aplicações iOS.</p>
<p>O desenvolvedor Objective-C precisa se  preocupar com o gerenciamento de memória em suas aplicações, basicamente isso significa alocar a memória que será usada pelos objetos, utilizá-la e depois liberar essa memória. Esquecer de liberar a memória, ou liberá-la enquanto ainda está em uso, são problemas que podem causar mau funcionamento da aplicação e inclusive o famoso &#8220;crash&#8221;,  fazendo-a fechar inesperadamente.</p>
<p>O mecanismo para gerenciamento de memória usado em Objective-C é conhecido como <em>reference counting</em>. Para alocar a memória manualmente, enviamos uma mensagem <code>alloc</code> (uma invocação de método) para uma classe. Uma receita comum para a criação de objetos é invocar o método <code>init</code> para o retorno de uma invocação ao <code>alloc</code>, como no exemplo para instanciar uma <code>NSArray</code>:</p>
<pre class="brush: objc; title: ; notranslate">
NSArray *array = [[NSArray alloc] init]
</pre>
<p>O retorno dessa chamada a <code>init</code> é uma referência a um objeto pronto para uso, mas por quanto tempo esse objeto ficará em uso? Quando vamos permitir que ele seja varrido da memória?</p>
<p>Podemos invocar o <code>retain</code> para um objeto e isso soma 1 ao seu contador de referências. O método <code>release</code> é usado para subtrair 1 do contador, podendo possibilitar sua desalocação. Se esse balanço é comprometido (que é o que acontece quando esquecemos de invocar <code>release</code> para uma referência que não será mais usada) começam aparecer os tais vazamentos de memória. Esse processo manual de alocação e liberação de memória pode ser ilustrado como na <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html">imagem abaixo</a>:</p>
<p><img src="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Art/memory_management.jpg" alt="" width="568px;" height="308px;" /></p>
<p>Aliás, é bastante didático <a href="https://developer.apple.com/library/mac/#documentation/developertools/conceptual/InstrumentsUserGuide/ViewingandAnalyzingData/ViewingandAnalyzingData.html">utilizar o Instruments</a> para poder aprender e visualizar o reference count de cada objeto em memória.</p>
<p>A ideia do ARC é facilitar, tirando a nossa responsabilidade de invocar <code>retain</code> e <code>release</code>: essa tarefa passa a ser executada por debaixo dos panos, com a ajuda do compilador. Para desenvolver código que aproveita ao máximo essa funcionalidade é preciso pensar na forma como os objetos se relacionam entre si durante a execução de seu programa. Se optar pelo ARC, você não poderá mais invocar <code>retain</code> e <code>release</code> explicitamente, essas invocações serão incluídas automaticamente pelo compilador. Mas como o compilador decide quando usar esses métodos? Ele considera os chamados modificadores de ciclo de vida, na declaração das referências.</p>
<p>Quando declaramos uma propriedade podemos utilizar esses modificadores de ciclo de vida, é isso que define como um objeto é tratado em termos de gerenciamento de memória. O modificador de ciclo de vida padrão para uma proprieade é o <code>assign</code>. Além dele podemos usar <code>retain</code> e <code>copy</code>. Com o ARC surgiram o <code>strong</code> e o <code>weak</code>.</p>
<h3>assign</h3>
<p>É o modificador padrão de ciclo de vida. A propriedade é apenas um ponteiro para o objeto atribuído a ela, não soma ou subtrai do contador de referências e portanto não interfere no gerenciamento da memória para o objeto referenciado. Se o objeto for liberado da memória em um outro ponto do código, a referência apontada pela propriedade se tornará inválida, pois passa a apontar para um endereço de memória que não existe mais. Uma invocação de método nessa propriedade irá causar um erro de execução.</p>
<pre class="brush: objc; title: ; notranslate">
@property NotaFiscal *nota;
</pre>
<h3>retain</h3>
<p>Atribuir um objeto para a propriedade declarada com esse modificador soma 1 ao seu contador de referências. Usamos <code>retain</code> para tornar explícito que essa propriedade, após atribuída, estará disponível enquanto o objeto que a declara estiver sendo utilizando:</p>
<pre class="brush: objc; title: ; notranslate">
@property(retain) Produto *produto;
</pre>
<h3>copy</h3>
<p>Usado normalmente quando a propriedade se refere a um objeto que pode ser mutável como strings, arrays e dictionaries. Todos esses tipos têm subclasses que podem gerar objetos mutáveis, porém quando passamos esses objetos como parâmetro a intenção normalmente é a de usar <em>valores</em> no método que recebe o parâmetro, não queremos permitir nenhuma alteração no objeto original. Como uma cópia defensiva, para não expor os atributos do nosso objeto a modificações indesejadas. Se esse for o caso podemos usar o modificador <code>copy</code>, isso vai garantir que o objeto seja copiado no momento da atribuição, essa cópia inicia sua vida com seu contador de referência valendo 1.</p>
<pre class="brush: objc; title: ; notranslate">
@property(copy) NSString *nomeCompleto;
</pre>
<p>Todos esses modificadores são tratados automaticamente pelo ARC. Isso significa que o próprio compilador vai se encarregar de procurar o melhor momento para adicionar envios de mensagem release para liberar a memória alocada por essas declarações, quando isso for necessário. O ARC também disponibiliza alguns modificadores novos, que vem de encontro com a ideia de livrar o desenvolvedor da preocupação com a alocação de memória:</p>
<h3>strong</h3>
<p>Quando um objeto é atribuído o contador de referências é incrementado, e a responsabilidade por fazer um decremento no contador é do objeto que possui a propriedade. O funcionamento é análogo ao do modificador <code>retain</code>.</p>
<pre class="brush: objc; title: ; notranslate">
@property(strong) Pessoa *cliente;
</pre>
<h3>weak</h3>
<p>Atribuir um objeto não incrementa o contador, semelhante ao modificador <code>assign</code>. Porém se a memória alocada para o objeto for liberada, a propriedade automaticamente torna-se <code>nil</code>. Essa diferença com relação ao <code>assign</code> é crucial pois se for invocado um método nessa propriedade (agora com o valor <code>nil</code>) não haverá um erro de execução, como se ela fosse ignorada.</p>
<pre class="brush: objc; title: ; notranslate">
@property(weak) Endereço *endereco;
</pre>
<p>A vantagem de usar <code>strong</code> e <code>weak</code> com o ARC é poder pensar no grafo de objetos e suas relações, sem se preocupar com o contador de referências. Uma preocupação que ainda temos é a de garantir que não haverá nenhuma referência cíclica impedindo algum objeto de ser liberado da memória. Imagine uma propriedade chamada cliente que contém uma referência com modificador strong para um objeto do tipo Pessoa. Esse objeto internamente faz uma referência para uma instância de Endereco, veja a declaração dessas classes:</p>
<pre class="brush: objc; title: ; notranslate">
@interface Pessoa
@property(strong) Endereco *endereco;
@end
</pre>
<pre class="brush: objc; title: ; notranslate">
@interface Endereco
@property(strong) Pessoa *pessoa;
// outras propriedades...
@end
</pre>
<pre class="brush: objc; title: ; notranslate">
@implementation Endereco
-(id) initComLogradouro:(NSString *)_logradouro eNumero:(NSString *)_numero paraPessoa:(Pessoa *)_pessoa {
    self = [super init];
    if(self) {
        self.pessoa = _pessoa;
    }
    // restante das atribuições...
    return self;
}
</pre>
<p>Podemos pensar em um sistema de cadastro que crie objetos do tipo <code>Pessoa</code> e <code>Endereço</code>, e faça as associações entre eles:</p>
<pre class="brush: objc; title: ; notranslate">
@interface Cadastro
@property(strong) Pessoa *pessoa;
- (void) cadastraPessoaComNome:(NSString *)nome;
@end
</pre>
<p>E essa poderia ser uma implementação para o método <code>cadastraPessoa</code>:</p>
<pre class="brush: objc; title: ; notranslate">
- (void) cadastraPessoa:(NSString *)nome {
    self.pessoa = [[Pessoa alloc] initComNome:nome];
    Endereco *e = [[Endereco alloc] initComLogradouro:@&quot;Rua Vergueiro&quot; eNumero:3185 paraPessoa:self.pessoa];
}
</pre>
<p>Dentro do método <code>cadastraPessoa</code>: é criado um objeto do tipo <code>Pessoa</code>, quando ele é atribuído à propriedade <code>pessoa</code>, o contador de referência é incrementado. O compilador irá inserir o envio da mensagem release para a propriedade <code>pessoa</code> da classe <code>Cadastro</code>. Mas perceba que o contador de referências para esse objeto foi incrementado também durante a execução do inicializador <code>initComLogradouro:eNumero:paraPessoa:</code>. Nesse momento o contador de referências para o objeto pessoa criado no método <code>cadastraPessoa</code>: tem o total de 2.</p>
<p>Para o gerenciador de memória liberar o objeto do tipo <code>Cadastro</code> utilizado no exemplo, uma das coisas que precisa ser feito é a liberação do objeto apontado pela propriedade do tipo <code>Pessoa</code>. Para isso será subtraído 1 do contador de referências, agora o contador tem 1, e o objeto referenciado por <code>pessoa</code> não será liberado da memória. Faz sentido! Mas não é o comportamento esperado, já que o objeto criado pelo cadastro deveria ser liberado da memória junto com o cadastro que o criou. É um vazamento!</p>
<p>Para evitar isso, podemos usar o modificador de ciclo de vida <code>weak</code> na propriedade pessoa de endereço, dessa forma a propriedade será <code>nil</code> quando esse objeto for liberado a qualquer momento, e não há o risco de uma referência para o objeto do tipo <code>Pessoa</code> ficar pendente (<code>dangling</code>). Uma forma de pensar nesse tipo de relacionamento é: endereço pertence a uma pessoa, portanto ele aponta para a pessoa de forma <strong>weak</strong>, se a pessoa for liberada, endereço não tem que interferir nisso. Já a pessoa quer ter certeza de que o endereço estará sempre disponível para ela, portanto ela aponta para o endereço de forma <strong>strong</strong>.</p>
<p>Vamos nos apoiar no ARC para corrigir o problema, podemos declarar as classes <code>Pessoa</code> e <code>Endereço</code> da seguinte forma:</p>
<pre class="brush: objc; title: ; notranslate">
@interface Pessoa

@property(strong) Endereco *endereco;

@end
</pre>
<pre class="brush: objc; title: ; notranslate">
@interface Endereco

@property(weak) Pessoa *pessoa;

@end
</pre>
<p>Existem modificadores específicos para variáveis de instância. Além do <code>__strong</code> e do <code>__weak</code> que funcionam da mesma forma que os análogos <code>strong</code> e <code>weak</code> utilizados em propriedades, existem também:</p>
<h3>__unsafe_unretained</h3>
<p>Semelhante ao <code>_weak</code>, porém a variável não recebe o valor nil quando a memória é liberada, o valor continua sendo um ponteiro que agora fica pendente. Equivalente ao <code>assign</code> para propriedades.</p>
<h3>__autoreleasing</h3>
<p>Libera a memória utilizada para armazenar um objeto passado como parâmetro para um método assim que ele retorna. Garante que dentro da execução do método o objeto vai estar disponível, mas só durante esse período.</p>
<p>Existem outros aspectos relacionados ao gerenciamento de memória com o ARC. Por exemplo: não é possível usar <code>retain</code> e <code>release</code> explícitamente com o ARC habilitado, isso irá gerar erros de compilação. Também não é possível usar objetos do tipo <code>NSAutoreleasePool</code>, para essa funcionalidade devemos utilizar um bloco @autoreleasepool. É possível desabilitar o ARC em um projeto para arquivos específicos, isso significa que você pode utilizar bibliotecas &#8220;pré-ARC&#8221;, mesmo se sua aplicação quiser usar este novo contador automático de referêncais.</p>
<p>Vale lembrar que o código para atribuição e leitura dos dados de uma proprieade com seus devidos retains serão gerados automaticamente pelo compilador ao usar a diretiva <code>@synthesize</code>.</p>
<p>No curso <a href="http://www.caelum.com.br/curso/ip-67-desenvolvimento-movel-ios-5-iphone-ipad/" target="_blank">IP-67</a> da Caelum esse assunto é debatido e relacionado com vários outros aspectos do desenvolvimento para aplicações iOS.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/gerenciamento-de-memoria-e-o-arc-no-objective-c/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Organização de testes de aceitação com PageObjects</title>
		<link>http://blog.caelum.com.br/organizacao-de-testes-de-aceitacao-com-pageobjects/</link>
		<comments>http://blog.caelum.com.br/organizacao-de-testes-de-aceitacao-com-pageobjects/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 14:30:59 +0000</pubDate>
		<dc:creator>Leonardo Wolter</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[aceitação]]></category>
		<category><![CDATA[fj-16]]></category>
		<category><![CDATA[fj-87]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4922</guid>
		<description><![CDATA[Testes de aceitação são extremamente úteis quando se trata de verificar se as funcionalidades de um sistema estão se comportando corretamente sem que tenhamos de testar manualmente a aplicação, abrindo um navegador, navegando por ela e visualizar os resultados. Como poderíamos automatizar esses testes que envolvem realizar a navegação na aplicação? Para isso ser possível, <a href="http://blog.caelum.com.br/organizacao-de-testes-de-aceitacao-com-pageobjects/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/04/test.jpg" width="240" />
		</p><p>Testes de aceitação são extremamente úteis quando se trata de verificar se as funcionalidades de um sistema estão se comportando corretamente sem que tenhamos de testar manualmente a aplicação, abrindo um navegador, navegando por ela e visualizar os resultados. Como poderíamos automatizar esses testes que envolvem realizar a navegação na aplicação?</p>
<p>Para isso ser possível, existem algumas ferramentas que permitem tal trabalho, simulando a interação de um usuário com a aplicação. Esse é o caso do <a href="http://blog.caelum.com.br/testes-de-aceitacao-com-o-selenium/">Selenium</a> que, com a assistência do <a href="http://junit.org/">JUnit</a>, pode facilitar o trabalho de escrever tais testes.</p>
<p>Para vermos como o Selenium pode nos ajudar, vamos considerar uma página contendo simples HTML, que ao clicarmos em um link dela, seremos redirecionados para outra página.</p>
<pre class="brush: xml; title: ; notranslate">

 &lt;a class=&quot;botao&quot; href=&quot;outra_pagina.html&quot;&gt;Clique Aqui&lt;/a&gt;
</pre>
<p>Quando clicado, o link deve redirecionar para a <code>outra_pagina.html</code>, que tem o conteúdo:</p>
<pre class="brush: xml; title: ; notranslate">&lt;/pre&gt;
&lt;h2&gt;Estou na outra página!&lt;/h2&gt;
&lt;pre&gt;
</pre>
<p>Com essas páginas, podemos escrever um teste, usando o Selenium, para que ele clique no link e em seguida verifique se estamos na outra página. Para isso, podemos escrever um pequeno teste com o JUnit usando a API do Selenium:</p>
<pre class="brush: java; title: ; notranslate">
@Test
public void deveIrParaAOutraPagina() {
   WebDriver driver = new FirefoxDriver();
   driver.navigate().to(&quot;http://localhost:8080/pagina.html&quot;);

   driver.findElement(By.className(&quot;botao&quot;)).click();

   String texto = driver.findElement(By.tagName(&quot;h2&quot;)).getText();
   assertEquals(&quot;Estou na outra página!&quot;, texto);
}
</pre>
<p>Com a API do Selenium, esse código parece simples, não é? Mas imagine se precisássemos fazer várias ações e navegar por diversas páginas para conseguirmos testar uma funcionalidade. Um possível exemplo seria o login aplicação, onde uma possibilidade de teste é:</p>
<pre class="brush: java; title: ; notranslate">
@Test
public void aoSeLogarNaAplicacaoDeveMostrarQueEstaLogado(){
   WebDriver driver = new FirefoxDriver();
   driver.navigate().to(&quot;http://localhost:8080/login.html&quot;);

   // pega uma referencia para o formulário de login que estará na tela
   WebElement formulario = driver.findElement(By.tagName(&quot;form&quot;));

   // preenche usuário e senha
   driver.findElement(By.id(&quot;usuario&quot;)).sendKeys(&quot;joao&quot;);
   driver.findElement(By.id(&quot;senha&quot;)).sendKeys(&quot;123456&quot;);

   // submete o formulário
   formulario.submit();

   // na próxima tela, o login desse usuário deveria estar aparecendo
   String usuarioLogado = driver.findElement(By.id(&quot;usuario-logado&quot;)).getText();

   // verifica se o joao conseguiu fazer o login
   assertEquals(&quot;joao&quot;, usuarioLogado);
}
</pre>
<p>Apesar de funcionar perfeitamente, o código acima possui um grave problema: lê-lo já está extremamente mais complexo do que o teste que havíamos feito antes! Agora, imagine se estivéssemos escrevendo testes para uma funcionalidade que envolva interação com várias outras telas?</p>
<p>Para simplificar e organizar esse código de teste, vamos separar cada uma das telas em classes diferentes, ou seja, para a tela de login vamos criar uma classe chamada <code>TelaDeLogin</code> e para a página interna uma classe chamada <code>PaginaInterna</code>, dessa forma poderíamos ter o método <code>loga</code> com seguinte código para a <code>TelaDeLogin</code>:</p>
<pre class="brush: java; title: ; notranslate">
public class TelaDeLogin {

   public void abre() {
      driver.navigate().to(&quot;http://localhost:8080/login.html&quot;);
   }

   public void loga(String usuario, String senha) {
      // pega uma referencia para o formulário na tela
      WebElement formulario = driver.findElement(By.tagName(&quot;form&quot;));

      // preenche usuário e senha
      driver.findElement(By.id(&quot;usuario&quot;)).sendKeys(usuario);
      driver.findElement(By.id(&quot;senha&quot;)).sendKeys(senha);

      // submete o formulário
      formulario.submit();
   }
}
</pre>
<p>Note que o código acima ainda não compila, pois precisamos de uma referência para o <code>WebDriver</code>. Podemos passar a recebê-la via construtor:</p>
<pre class="brush: java; title: ; notranslate">
public class TelaDeLogin {
   private WebDriver driver;

   public TelaDeLogin(WebDriver driver) {
      this.driver = driver;
   }

   public void abre() {
      // navega para a tela de login
   }

   public void loga(String usuario, String senha) {
      // código que usa o Selenium para fazer o login
   }
}
</pre>
<p>Dessa forma, podemos usar a nova classe <code>TelaDeLogin</code> no lugar do código do Selenium em nossas classes de teste. Com isso, o teste ficará parecido com:</p>
<pre class="brush: java; title: ; notranslate">
public class TestesDeAceitacao extends SeleniumTest {

   private TelaDeLogin telaDeLogin;

   // Instanciamos a base de nossa aplicacao
   @Before
   public void setup() {
      WebDriver driver = new FirefoxDriver();
      this.telaDeLogin = new TelaDeLogin(driver);
   }

   // Efetuamos o teste
   @Test
   public void aoSeLogarNaAplicacaoDeveMostrarQueEstaLogado(){
      telaDeLogin.abre();
      telaDeLogin.loga(&quot;joao&quot;,&quot;123456&quot;);

      // na próxima tela, o login desse usuário deveria estar aparecendo
      String usuarioLogado = driver.findElement(By.id(&quot;usuario-logado&quot;)).getText();

      // verifica se o joao conseguiu fazer o login
      assertEquals(&quot;joao&quot;, usuarioLogado);
   }
}
</pre>
<p>O código do teste melhorou, mas ainda continua com problemas, um deles é que ainda usamos a API do Selenium diretamente dentro do teste e novamente, se ele fosse um pouco mais complexo, continuaria difícil de ler seu código. Como o trecho que ainda está usando o código do Selenium direto no teste diz respeito à página interna do sistema, podemos levar esse código para a classe <code>PaginaInterna</code>, dessa forma teremos:</p>
<pre class="brush: java; title: ; notranslate">
public class PaginaInterna {
   private WebDriver driver;

   public PaginaInterna(WebDriver driver) {
      this.driver = driver;
   }

   public boolean estaLogado(String usuario) {
      String usuarioLogado = driver.findElement(By.id(&quot;usuario-logado&quot;)).getText();

      return usuarioLogado.equals(usuario);
   }
}
</pre>
<p>Dessa maneira, podemos fazer uma simples refatoração no nosso teste, para usar a nova classe implementada:</p>
<pre class="brush: java; title: ; notranslate">
   @Test
   public void aoSeLogarNaAplicacaoDeveMostrarQueEstaLogado() {
      String usuario = &quot;joao&quot;;
      telaDeLogin.abre();
      telaDeLogin.loga(usuario, &quot;123456&quot;);

      boolean estaLogado = new PaginaInterna(driver).estaLogado(usuario);
      assertTrue(estaLogado);
   }
</pre>
<p>Agora estamos num nível melhor, mas continua tendo pontos para melhorar. O principal deles agora, é que toda troca de tela que existir em nosso teste, precisamos instanciar um objeto para a nova tela, passar o <code>driver</code> como parâmetro, para aí sim, podermos invocar o método. Note que ao fazermos o login com sucesso, nesse caso, sempre seremos redirecionados para a mesma página, sendo assim, poderíamos fazer o método <code>loga</code> já retornar uma instância de <code>PaginaInterna</code> para nós e assim, só precisaríamos chamar o método <code>verificaSeEstaLogado</code>:</p>
<pre class="brush: java; title: ; notranslate">
public class TelaDeLogin {

   // construtor e atributo driver

   public PaginaInterna loga(String usuario, String senha) {
      // pega uma referencia para o formulário na tela
      WebElement formulario = driver.findElement(By.tagName(&quot;form&quot;));

      // preenche usuário e senha
      driver.findElement(By.id(&quot;usuario&quot;)).sendKeys(usuario);
      driver.findElement(By.id(&quot;senha&quot;)).sendKeys(senha);

      // submete o formulário
      formulario.submit();

      return new PaginaInterna(driver);
   }
}
</pre>
<p>Essa alteração na classe <code>TelaDeLogin</code> nos permite encadear as chamadas dos métodos <code>loga</code> e <code>verificaSeEstaLogado</code> no nosso teste de aceitação:</p>
<pre class="brush: java; title: ; notranslate">
   @Test
   public void aoSeLogarNaAplicacaoDeveMostrarQueEstaLogado() {
      String usuario = &quot;joao&quot;;
      telaDeLogin.abre();

      boolean estaLogado = telaDeLogin.loga(usuario, &quot;123456&quot;).estaLogado(usuario);
      assertTrue(estaLogado);
   }
</pre>
<p>Agora nosso teste está bem mais legível, e o código do Selenium todo encapsulado dentro de classes, que chamamos de <code><a href="http://code.google.com/p/selenium/wiki/PageObjects">PageObject</a></code>s. Ainda há brechas que precisam de melhoras. Podemos fazer o método <code>abre()</code> retornar a própria instância de <code>TelaDeLogin</code> e, com isso, poderíamos ter todos os métodos encadeados, o que faria o teste ficar como:</p>
<pre class="brush: java; title: ; notranslate">
   @Test
   public void aoSeLogarNaAplicacaoDeveMostrarQueEstaLogado(){
      String usuario = &quot;joao&quot;;

      boolean estaLogado = telaDeLogin.abre().loga(usuario, &quot;123456&quot;).estaLogado(usuario);
      assertTrue(estaLogado);
   }
</pre>
<p>Com isso, temos um código de teste bem mais legível, onde toda a API do Selenium está encapsulado dentro de classes que representam as páginas, formando os Page Objects.</p>
<p>Que outras ferramentas e práticas você utiliza para facilitar seus testes de aceitação?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/organizacao-de-testes-de-aceitacao-com-pageobjects/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Flexibilidade em páginas para dispositivos móveis com media queries</title>
		<link>http://blog.caelum.com.br/flexibilidade-em-paginas-para-dispositivos-moveis-com-media-queries/</link>
		<comments>http://blog.caelum.com.br/flexibilidade-em-paginas-para-dispositivos-moveis-com-media-queries/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 11:29:45 +0000</pubDate>
		<dc:creator>Sérgio Lopes</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[viewport]]></category>
		<category><![CDATA[wd-43]]></category>
		<category><![CDATA[wd-47]]></category>
		<category><![CDATA[web mobile]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4854</guid>
		<description><![CDATA[Já fez seu site mobile? Explore o mercado que mais cresce no Brasil e no mundo com as melhores práticas de Web mobile. No artigo sobre viewport, aqui do Blog, vimos como criar uma página com tamanho adequado aos diversos dispositivos que temos que lidar hoje em dia. Se colocarmos um viewport com width=320, por <a href="http://blog.caelum.com.br/flexibilidade-em-paginas-para-dispositivos-moveis-com-media-queries/#more-'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/tudo.jpg" width="240" />
		</p><p><em>Já fez seu site mobile? Explore o mercado que mais cresce no Brasil e no mundo com as melhores práticas de Web mobile.</em></p>
<p>No <a href="http://blog.caelum.com.br/pixels-pixels-ou-pixels-dicas-de-web-mobile-com-viewport/">artigo sobre viewport</a>, aqui do Blog, vimos como criar uma página com tamanho adequado aos diversos dispositivos que temos que lidar hoje em dia.</p>
<p>Se colocarmos um viewport com <em>width=320</em>, por exemplo, conseguimos criar uma página para iPhone e outros smartphones normalmente. Mas e se a página for aberta num iPad de <em>768px</em> de resolução? Ou em um tablet Android de <em>600px</em> de largura? Ou um smartphone Android de <em>533px</em> em modo paisagem?</p>
<p><b>Criar sites específicos para cada tamanho de tela não é a melhor solução.</b></p>
<p>Podemos então colocar o viewport com <code>width=device-width</code> e codificar nosso HTML e CSS para usarem <em>100%</em> da largura, <b>flexibilizando nosso layout</b>. Mas será que nosso layout vai ficar bonito tanto em um smartphone de 240px quanto num tablet com 1024px?</p>
<p>No último site mobile que fizemos, o do <a href="http://www.arquiteturajava.com.br/">livro Arquitetura Java</a>, usar um layout flexível deixava a página muito usável em telas pequenas (como num Nokia de 240px) mas não em telas maiores (como em um iPad):</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/layout-flexivel.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/layout-flexivel.jpg" alt="" title="Layout flexível não dá muito certo para tamanhos de telas muito diferentes" width="500" height="400" class="aligncenter size-full wp-image-4898" /></a></p>
<p>Só fazer layouts flexíveis também não é a melhor solução. Precisamos ajustar o design de acordo com o dispositivo usado.</p>
<h2>Media types</h2>
<p>Desde muito tempo o CSS tem suporte para se definir regras que só valem em certo contexto. Os <a href="http://www.w3.org/TR/CSS2/media.html"><b>media types</b></a> permitem que se use estilos diferentes em situações diferentes e sempre foram muito usados para distinguir a renderização na tela da impressão:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;link rel=&quot;stylesheet&quot; href=&quot;estilos.css&quot; media=&quot;screen&quot;&gt;
   &lt;link rel=&quot;stylesheet&quot; href=&quot;impressao.css&quot; media=&quot;print&quot;&gt;
</pre>
<p>Todos os navegadores modernos suportam esse media type <code>print</code> que é aplicado apenas quando vamos imprimir uma página (útil para esconder o menu de navegação ou aumentar a fonte do texto, por exemplo).</p>
<p>Alguns celulares antigos suportavam também o tipo <code>handheld</code> para estilos específicos para sites mobile. Os smartphones modernos como iPhone e Android, porém, ignoram o media type <code>handheld</code> pois são capazes de renderizar sites completos e não apenas as versões simples feitas para os celulares antigos.</p>
<p>Como então escrever CSS específico para mobile pensando em smartphones e tablets que não se encaixam no media querie <code>handheld</code>? Novos media queries!</p>
<h2>CSS3 media queries</h3>
<p>Melhor do que separar os dispositivos em desktop (<code>screen</code>) e mobile (<code>handheld</code>), os novos media queries permitem que foquemos principalmente no <b>tamanho da tela</b> onde vamos exibir o conteúdo.</p>
<p>É possível criar um CSS que só se aplique a tamanhos de tela de, no máximo, <em>320px</em> por exemplo (como um iPhone em modo retrato):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;link rel=&quot;stylesheet&quot; href=&quot;iphone.css&quot;
      media=&quot;screen and (max-width: 320px)&quot;&gt;
</pre>
<p>Existem diversas opções de media queries com bastante suporte. Além da <code>max-width</code>, podemos usar <code>min-width</code>, <code>width</code> e <code>device-width</code> &#8211; e todas as variações delas com <code>height</code>.</p>
<p>A diferença entre <code>width</code> e <code>device-width</code> é se estamos pensando em <a href="http://blog.caelum.com.br/pixels-pixels-ou-pixels-dicas-de-web-mobile-com-viewport/">CSS pixels ou no tamanho do viewport</a>. Geralmente não é boa prática depender do tamanho físico do aparelho então não usamos tanto <code>device-width</code>.</p>
<p>Uma decisão que precisa ser tomada é de se usar <code>max-width</code> ou <code>min-width</code>. O <em>max</em> é bom para quando temos um layout Desktop pronto e queremos adaptá-lo para dispositivos menores &#8211; vamos então definindo novas regras que se aplicam só aos dispositivos de no máximo certo tamanho. Já o <em>min</em> pode ser útil quando criamos um site só mobile ou começamos pelo mobile &#8211; nesse caso, é mais fácil ter um layout base e ir customizando para dispositivos maiores, com no mínimo certo tamanho.</p>
<h2>Mais media queries</h2>
<p>Além dos media queries de tamanho, aparelhos mais modernos suportam também um media querie que pega a orientação do dispositivo:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;link rel=&quot;stylesheet&quot; href=&quot;phones.css&quot;
      media=&quot;screen and (min-width: 320px) and (orientation: portrait)&quot;&gt;
</pre>
<p>Isso pode ser útil para customizar a experiência do site de acordo com como o usuário está segurando o aparelho. É <a href="http://www.netmagazine.com/features/designing-touch">sabido</a>, por exemplo, que um celular em modo retrato é mais usável com navegação na parte de baixo à esquerda; e, no modo paisagem, com navegação no topo e nas laterais.</p>
<div id="attachment_4899" class="wp-caption aligncenter" style="width: 510px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/touch-areas.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/touch-areas.png" alt="" title="Áreas quentes para toque num smartphone comum em retrato e paisagem" width="500" height="320" class="size-full wp-image-4899" /></a><p class="wp-caption-text">Áreas quentes para toque num smartphone comum em retrato e paisagem</p></div>
<p>Além de declarar as media queries na tag <code>&lt;link&gt;</code> no HTML, podemos também fazer direto dentro do arquivo CSS (podemos juntar tudo num arquivo CSS só e economizar requests):</p>
<pre class="brush: css; title: ; notranslate">
/* regra aplicada em todo lugar */
body { background: blue; }

/* aplica somente a partir de 320px */
@media screen and (min-width: 320px) {
   body { font-size: 80%; }
}

/* aplica somente a partir de 480px em landscape */
@media screen and (min-width: 480px) and (orientation: landscape) {
   nav { float: left; }
}
</pre>
<p>Há ainda como mirar dispositivos de alta resolução (como iPhones e iPads com Retina Display) com <code>device-pixel-ratio</code> para provermos imagens de melhor qualidade quando elas forem úteis. Ou ainda a opção <code>(color)</code> que permite distinguir entre dispositivos coloridos ou não (como um ereader ou Kindle).</p>
<p>Temos muitas outras opções de media queries na <a href="http://www.w3.org/TR/css3-mediaqueries/">especificação do W3C</a> e várias delas <a href="http://caniuse.com/css-mediaqueries">já disponíveis nos aparelhos de hoje</a>.</p>
<h2>Media queries comuns</h2>
<p>E quais valores usar no projeto para adaptar para diferentes larguras? O ideal seria fazer as adaptações conforme seu layout exige (seria até possível fazer um layout só com porcentagens e sem media querie nenhum que funcione em diversos tamanhos de tela).</p>
<p>Mas se você pensa nos dispositivos mais comuns de hoje, existem algumas combinações de media queries famosas. O projeto <a href="https://github.com/malarkey/320andup/">320andup</a> por exemplo sugere que você faça um layout base pensando em 320px e depois adapte para outros tamanhos com:</p>
<pre class="brush: css; title: ; notranslate">
@media print { }

@media only screen and (min-width: 480px) { }
@media only screen and (min-width: 600px) { }
@media only screen and (min-width: 992px) { }
@media only screen and (min-width: 1382px) { }

@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) { }
</pre>
<p>Há a regra para impressão e outras 4 pensando em tamanhos comuns de smartphones e tablets. A última regra foca em dispositivos com alta resolução como os Retina Display e Android modernos. (o uso da keyword <code>only</code> serve apenas para esconder essas regras de navegadores antigos que não suportem media queries mas suportam o media type <code>screen</code>)</p>
<p>No nosso site <a href="http://www.arquiteturajava.com.br">arquiteturajava.com.br</a> que suporta mobile, usamos o layout base pensando em 240px e os seguintes media queries:</p>
<pre class="brush: css; title: ; notranslate">
@media screen and (min-width:320px) { }
@media screen and (min-width:480px) { }
@media screen and (min-width:600px) { }
@media screen and (min-width:768px) { }
@media screen and (min-width:992px) { }
</pre>
<p>Nós inclusive <a href="https://github.com/caelum/arquiteturajava.com.br">abrimos o código do site no Github</a> para servir de exemplo de design mobile com media queries e viewport.</p>
<div id="attachment_4901" class="wp-caption aligncenter" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/tudo.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/03/tudo-300x139.jpg" alt="" title="Site do livro aberto em tudo quanto é dispositivo: tablet, ipad, smartphone, tv, desktop, ereader" width="300" height="139" class="size-medium wp-image-4901" /></a><p class="wp-caption-text">Site do livro aberto em tudo quanto é dispositivo: tablet, ipad, smartphone, tv, desktop, ereader</p></div>
<h2>Conclusão</h2>
<p>As novas media queries do CSS3 são muito úteis para adaptar nosso site a diferentes resoluções. E o melhor é que contam com excelente suporte nos navegadores mobile.</p>
<p>O título desse post não está muito correto. Apesar das media queries serem fundamentais para a Web mobile (e terem nascido nesse meio), todo os navegadores Desktop modernos também suportam os media queries de CSS3 (até o IE). Usar <code>max-width</code>, por exemplo, vai fazer com que o layout se ajuste ao tamanho da janela do navegador.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/flexibilidade-em-paginas-para-dispositivos-moveis-com-media-queries/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

