O documento discute princípios de design de código e qualidade de código. Ele apresenta Guilherme Silveira como líder técnico, instrutor e palestrante sobre tópicos como escrever código limpo e evitar código ruim no futuro. O documento também fornece contatos de Guilherme Silveira.
64. def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
fonte pequena?
65. def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
agora sim? fonte 16
67. 23...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
68. 23...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
69. mas e se... 23...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
70. mas eese...
mas se... 23...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
71. mas eese...
mas ese... 23...
mas se...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
72. mas eese...
mas ese... 23...
mas ese...
mas se...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
73. mas eese...
mas ese... 23...
mas ese...
mas ese...
mas se...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
74. mas eese...
mas ese... 23...
mas ese...
mas ese...
mas se...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
75. mas eese...
mas ese... 23...
mas ese...
mas ese...
mas ese...
mas se...
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
77. def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
78. o fluxo é COMPLEXO
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
79. o fluxo éSEMANTICA
não há COMPLEXO
def _read_attribute(attr_name)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
if unserializable_attribute?(attr_name, column)
unserialize_attribute(attr_name)
else
column.type_cast(value)
end
else
value
end
end
end
121. def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
end
how many tests do I need?
how frequently does flow control appear?
126. how many ifs?
def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
end
Text
how frequently does flow control appear?
127. how many ifs?
def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
end
Text
how frequently does flow control appear?
128. how many ifs?
how many fors?
def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
end
Text
how frequently does flow control appear?
129. how many ifs?
how many fors?
def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
end
Text
how frequently does flow control appear?
130. how many ifs?
how many fors?
def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
end
Text
how many tests do I need?
how frequently does flow control appear?
133. and now?
how frequently does flow control appear?
def cached_attributes
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }
.map { |col| col.name }
.to_set
end
145. o que acontece?
requisição remota?
Client client = clients.lookup(15L);
client.getName();
146. o que acontece?
requisição remota?
EJB 2 hell!
Client client = clients.lookup(15L);
client.getName();
147. o que acontece?
requisição remota?
EJB 2 hell!
Client client = clients.lookup(15L);
client.getName();
148. o que acontece?
requisição remota?
EJB 2 hell!
Client client = clients.lookup(15L);
client.getName();
Quer ver uma mágica?
149. o que acontece?
requisição HTTP?
inferno de “rest” proxy
aka active resource
Client client = clients.lookup(15L);
client.getName();
150. o que acontece se?
client.save
def save
database.save(this)
end
151. o que acontece se?
an HTTP remote request!?
client.save
def save
database.save(this)
end
152. o que acontece se?
an HTTP remote request!?
ClientRule.checkUniqueEnroll is invoked!?
client.save
def save
database.save(this)
end
153. o que acontece se?
an HTTP remote request!?
ClientRule.checkUniqueEnroll is invoked!?
“invisible invocation(s)” pattern
client.save
def save
database.save(this)
end
180. esse dói?
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo
181. esse dói?
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo
Maurício Aniche
182. esse dói?
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo
Como você testaria isso?
Maurício Aniche
183. esse dói?
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo
Como você testaria isso?
mock.assert(_.select(“select from ...”))?
Maurício Aniche
184. esse dói?
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo
Como você testaria isso?
mock.assert(_.select(“select from ...”))?
1 teste?
Maurício Aniche
190. Facinho...
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo limit 2
Martin Fowler
191. Facinho...
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo limit 2
sql também é linguagem...
Martin Fowler
192. Facinho...
select * from Contatos where a=b or (c=d && e=f)
order by primeiro_campo limit 2
sql também é linguagem...
mina gata hein...
Martin Fowler
193. menos de 5 testes não garanto
mas a cobertura diz “100%”...
mentirosa ...
203. declare dependência
e código no
CONSTRUTOR
mas e no Rails, Javabeans, Hibernate, etc?
204. java (the javabeans way) rails (the ruby way)
dumb constructor dumb constructor
getter+setter attr_accessor
the scala way
dumb constructor
val
205. java (the javabeans way) rails (the ruby way)
dumb constructor dumb constructor
public variable public variable
the scala way
dumb constructor
public variable
206. O padrão de OO no mercado é a
“orgia dos objetos” pattern.
Todo mundo pega todo mundo.
240. abra *.jsp, *.erb, *.ssp, *.similares
CTRL+F, if com algo != de boolean
CTRL+F, if com chamada != de boolean
Notas do Editor
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Esse é o gráfico de Requests/segundo do site da Caelum ao longo de duas semanas normais em Agosto/Setembro de 2010. Até que um belo dia acontece o lançamento da nova apostila de Rails 3 do curso RR-71 da Caelum...\n\n@sergio_caelum | Caelum | QCon São Paulo 2010\n
... e, em apenas um instante, os acessos ao Site quintuplicam! \n\nEnviamos uma campanha em newsletter para milhares de inscritos, divulgamos no Blog com milhares de leitores e várias pessoas twitam. Tudo simultaneamente, em uma fria manhã de quinta-feira.\n\nComo lidar com esse tipo de pico? Como gerenciar os recursos computacionais necessários para segurar o tranco? E mais, sem desperdiçar recursos nem antes e nem depois; afinal o normal do site não é esse volume de acessos e o pico logo acaba.\n\nPodemos lançar por partes. Enviar a newsletter aos poucos para pequenos grupos. Divulgar no Blog apenas no dia seguinte. Mas piorar a experiência dos usuários por limitações técnicas? Perder aquele momento de marketing onde milhares e milhares de pessoas estão falando de você?\n\nVocê passa a vida toda desenvolvendo um produto e querendo que ele dê certo. E um belo dia ele estoura em sucesso. Como seu sistema reage? Ele capota ou segura o tranco naquele momento importantíssimo de crescimento? No fim de 2009, sem sabermos, o portal da revista InfoExame fez uma matéria citando nossas apostilas abertas. Foi uma correria para downloads, muitos e muitos acessos no site. Imagine não aguentar o tranco em um momento tão especial e com tanta visibilidade como esse?\n\n@sergio_caelum | Caelum | QCon São Paulo 2010\n
A solução rápida e fácil? Cloud computing e computação elástica\n\n@sergio_caelum | Caelum | QCon São Paulo 2010\n