Dívidas são algo cotidiano. Empresas e pessoas contraem dívidas para operar seus negócios ou realizar sonhos e, com código é a mesma coisa. Vez ou outra admitimos algo fora dos padrões de qualidade para corrigir algum problema ou ter alguma vantagem sobre a concorrência. O grande problema é quando essa nossa dívida sai do controle gerando prejuízos não só para a empresa mas, nós desenvolvedores.
A falta de controle dessa dívida tem como maior efeito software rígido, difícil de entender e mudar, tornando-o mais suscetível a bugs. Para pagar o que devemos, temos que reverter esse quadro aumentando a facilidade em entender o código. Como fazer isso? Usando bons nomes!
Javascript per applicazioni complesse - Lo Stretto digitaleGiuseppe Pizzimenti
Mentre ogni giorno di più crescono e si fanno sempre più complessi gli ambiti nei quali Javascript si propone (e spesso impone) come strumento di sviluppo, viene da chiedersi se (e quando) si avvererà la legge di Atwood per la quale "ogni applicazione che può essere scritta in Javascript, sarà necessariamente scritta in Javascript".
Nell'attesa di scoprirlo meglio prepararsi con vecchi e nuovi patterns e best practices che ci consentono di realizzare software di qualità con uno dei linguaggi più duttili e trasversali di sempre.
Presentazione realizzata nell'ambito del progetto "Lo Stretto Digitale"
Javascript per applicazioni complesse - Lo Stretto digitaleGiuseppe Pizzimenti
Mentre ogni giorno di più crescono e si fanno sempre più complessi gli ambiti nei quali Javascript si propone (e spesso impone) come strumento di sviluppo, viene da chiedersi se (e quando) si avvererà la legge di Atwood per la quale "ogni applicazione che può essere scritta in Javascript, sarà necessariamente scritta in Javascript".
Nell'attesa di scoprirlo meglio prepararsi con vecchi e nuovi patterns e best practices che ci consentono di realizzare software di qualità con uno dei linguaggi più duttili e trasversali di sempre.
Presentazione realizzata nell'ambito del progetto "Lo Stretto Digitale"
Analizador sintáctico de Pascal escrito en BisonEgdares Futch H.
Este documento es un ejemplo de un analizador sintáctico (Parser) de Pascal, escrito en Bison. Incluye la generación de un Árbol de Sintaxis Abstracta (AST - Abstract Syntax Tree)
Practical JavaScript Programming - Session 2/8Wilson Su
JavaScript is one of the most popular skills in today’s job market. It allows you to create both client- and server-side applications quickly and easily. Having a solid understanding of this powerful and versatile language is essential to anyone who uses it.
“Practical JavaScript Programming” does not only focus on best practices, but also introduces the fundamental concepts. This course will take you from JavaScript basics to advanced. You’ll learn about topics like Data Types, Functions, Events, AJAX and more.
Practical JavaScript Programming - Session 3/8Wilson Su
JavaScript is one of the most popular skills in today’s job market. It allows you to create both client- and server-side applications quickly and easily. Having a solid understanding of this powerful and versatile language is essential to anyone who uses it.
“Practical JavaScript Programming” does not only focus on best practices, but also introduces the fundamental concepts. This course will take you from JavaScript basics to advanced. You’ll learn about topics like Data Types, Functions, Events, AJAX and more.
Como saber onde eu estou na carreira? Quais são as coisas que eu deveria investir e saber para ser considerado um desenvolvedor sênior ou para mudar de patamar? Como lidar com pessoas, dar feedback e receber feedback? E, mais importante como definir objetivos para que seu sonho se torne realidade.
"There are only two hard things in Computer Science: cache invalidation and naming things." - Phil Karlton
De acordo com várias pesquisas através dos anos foi constatado que a grande maioria dos programadores passa a maior parte do tempo lendo código. Apesar de não ajudar muito a criar bom design, os nomes ajudam e muito a evitar a criação de design ruim e um exemplo disso é o foco do DDD na linguagem ubíqua. O motivo nem sempre é claro mas, vive no subconsciente já que eles nos ajudam a entender problemas, relações entre conceitos e na comunicação com as diferentes partes da empresa/ambiente de trabalho. O problema com os nomes é justamente achar um. E, como não existe uma fórmula mágica para acha-los vamos tentar achar alguns casos em que podemos melhorar um nome e destrinchar um processo, extremamente útil, para descoberta de nomes.
Analizador sintáctico de Pascal escrito en BisonEgdares Futch H.
Este documento es un ejemplo de un analizador sintáctico (Parser) de Pascal, escrito en Bison. Incluye la generación de un Árbol de Sintaxis Abstracta (AST - Abstract Syntax Tree)
Practical JavaScript Programming - Session 2/8Wilson Su
JavaScript is one of the most popular skills in today’s job market. It allows you to create both client- and server-side applications quickly and easily. Having a solid understanding of this powerful and versatile language is essential to anyone who uses it.
“Practical JavaScript Programming” does not only focus on best practices, but also introduces the fundamental concepts. This course will take you from JavaScript basics to advanced. You’ll learn about topics like Data Types, Functions, Events, AJAX and more.
Practical JavaScript Programming - Session 3/8Wilson Su
JavaScript is one of the most popular skills in today’s job market. It allows you to create both client- and server-side applications quickly and easily. Having a solid understanding of this powerful and versatile language is essential to anyone who uses it.
“Practical JavaScript Programming” does not only focus on best practices, but also introduces the fundamental concepts. This course will take you from JavaScript basics to advanced. You’ll learn about topics like Data Types, Functions, Events, AJAX and more.
Como saber onde eu estou na carreira? Quais são as coisas que eu deveria investir e saber para ser considerado um desenvolvedor sênior ou para mudar de patamar? Como lidar com pessoas, dar feedback e receber feedback? E, mais importante como definir objetivos para que seu sonho se torne realidade.
"There are only two hard things in Computer Science: cache invalidation and naming things." - Phil Karlton
De acordo com várias pesquisas através dos anos foi constatado que a grande maioria dos programadores passa a maior parte do tempo lendo código. Apesar de não ajudar muito a criar bom design, os nomes ajudam e muito a evitar a criação de design ruim e um exemplo disso é o foco do DDD na linguagem ubíqua. O motivo nem sempre é claro mas, vive no subconsciente já que eles nos ajudam a entender problemas, relações entre conceitos e na comunicação com as diferentes partes da empresa/ambiente de trabalho. O problema com os nomes é justamente achar um. E, como não existe uma fórmula mágica para acha-los vamos tentar achar alguns casos em que podemos melhorar um nome e destrinchar um processo, extremamente útil, para descoberta de nomes.
Palestra ministrada no TDC POA em 2016 sobre como usar esses dois princípios podem ajudar a melhorar seu código evitando alto acoplamento e problemas com referências nulas.
The document provides an introduction to object-oriented programming (OOP) principles and design patterns. It discusses the four pillars of OOP - abstraction, encapsulation, modularity, and hierarchy. It then defines what an object is in terms of its properties of state, behavior, and identity. The document outlines several OOP principles like least astonishment, command query separation, tell don't ask, and the law of Demeter. It concludes by briefly introducing some common design patterns like decorator, strategy, chain of responsibility, composite, template method, and facade.
This document discusses some common "gotchas" or surprises that newcomers to Ruby may encounter. It covers topics like truthy and falsey values in Ruby (only nil and false are falsey), the difference between and and && operators (and has higher precedence than =), that constants can be reassigned, and the differences between blocks, procs, and lambdas. The document is intended to help new Ruby programmers avoid surprises by explaining behaviors that may differ from other languages. It includes code examples to illustrate each point and provides references for further reading.
Palestra sobre domínio que usa os conceitos definidos por Eric Evans (DDD) para explicar domínios e traçar um paralelo entre o Conway's law e a falta de domínio.
O documento discute interfaces em programação orientada a objetos. Ele explica que interfaces definem o comportamento esperado de um objeto e possibilitam a comunicação entre objetos, já que mostram quais mensagens um objeto pode receber. O documento também discute como interfaces devem ser definidas de forma coesa e respeitando certos princípios como notificar erros.
1. Apresentação sobre testes automatizados com TDD (Test Driven Development) por Augusto Pascutti e Nelson Senna. 2. Explicação dos diferentes níveis de teste e o que é TDD. 3. Demonstração prática de TDD ao desenvolver um teste unitário e implementação para salvar emails em uma newsletter.
O documento apresenta a agenda de uma palestra sobre Test Driven Development (TDD). A agenda inclui uma primeira palestra, uma discussão sobre o que não é TDD, uma explicação do que é TDD, e várias etapas de desenvolvimento de um projeto usando TDD.
O documento discute a integração de sistemas usando RabbitMQ como middleware de mensagens. Ele explica como RabbitMQ funciona usando componentes como exchanges, queues e bindings para encaminhar mensagens de produtores para consumidores de maneira assíncrona e com baixo acoplamento. O documento também discute porque o RabbitMQ é uma boa opção para integração e fornece exemplos de como criar produtores e consumidores.
2. Eu sou…
• Desenvolvedor;
• PHP, Ruby, Python e JavaScript. Um pouco de Java e C# (Xamarin);
• Trabalho na BriteCore;
• Trabalho remotamente desde 2016;
• @nelson_senna
6. Classificação de débito técnico
Imprudente Prudente
Deliberado
Negligente
“Não temos tempo!” “Precisamos entregar,
depois vemos isso.”
“O que é OOD? OOP? Design?”
“Agora sabemos que
devíamos ter feito isso.”
8. –Martin Fowler
“Como uma dívida
financeira, o débito
técnico incorre em
pagamentos de juros,
que vêm na forma de
esforço extra que
temos que fazer no
futuro...”
12. “Um Big Ball of Mud
tem estrutura
desordenada,
espalhada, desleixada,
remendada e, código
espaguete”
–Brian Foote
13. Big Ball of Mud
• Os nomes de variáveis e funções pouco informativos ou enganosos
• Uso extensivo de variáveis globais
• Métodos com longas listas de parâmetros mal definidos
• Métodos longos e complicados e, executam várias tarefas não relacionadas
• Código duplicado
• O fluxo de controle é difícil de entender e difícil de seguir
• A intenção do programador é quase impossível de discernir
• O código é simplesmente ilegível e espalhado sem modularização clara
• O código exibe os sinais inconfundíveis de patch após patch nas mãos de vários
mantenedores, cada um dos quais mal entendeu as conseqüências do que estava
fazendo
• Sem documentação
14. Big Ball of Mud
A estrutura rígida que faz com que o
código fique difícil de entender, caro e
suscetível a erros.
15. “Da sinonímia dos termos organização e
conhecimento, retira-se que a síntese mais
produtiva, ou mais instigadora, para a
construção de uma idéia acerca da
organização do conhecimento na sociedade é
aquela que abstrai de organização, pelo verbo
organizar, os sentidos de ORGANIZAR, que
são os seguintes: estabelecer as bases de;
arrumar de determinado modo; colocar em
certa ordem.”
–Renato Rocha Souza
23. Nomes são descobertos!
Sem nome
Sem
sentido
Honesto
Honesto e
Completo
Faz o que o
nome diz
Intenção
↪ ↪ ↪ ↪ ↪ ↪
Abstração de
domínio
24. Nomes são descobertos!
Sem nome
Sem
sentido
Honesto
Honesto e
Completo
Faz o que o
nome diz
Intenção
↪ ↪ ↪ ↪ ↪ ↪
Abstração de
domínio
@arlobelshee
25. var rootJquery,
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
// Shortcut simple #id case for speed
rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]+))$/,
init = jQuery.fn.init = function( selector, context, root ) {
var match, elem;
// HANDLE: $(""), $(null), $(undefined), $(false)
if (!selector) {
return this;
}
// Method init() accepts an alternate rootjQuery
// so migrate can support jQuery.sub (gh-2101)
root = root || rootjQuery;
// Handle HTML strings
if (typeof selector === "string") {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
…
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
return (context || root).find(selector);
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor(context).find(selector);
}
// HANDLE: $(DOMElement)
} else if (selector.nodeType) {
this[0] = selector;
this.length = 1;
return this;
// HANDLE: $(function)
// Shortcut for document ready
} else if (isFunction(selector)) {
return root.ready !== undefined ? root.ready(selector) :
// Execute immediately if ready is not present
selector(jQuery);
}
return jQuery.makeArray(selector, this);
};
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
// HANDLE: $(#id)
} else {
elem = document.getElementById(match[2]);
if (elem) {
// Inject the element directly into the jQuery object
this[0] = elem;
this.length = 1;
}
return this;
}
26. var rootJquery,
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
// Shortcut simple #id case for speed
rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]+))$/,
init = jQuery.fn.init = function( selector, context, root ) {
var match, elem;
// HANDLE: $(""), $(null), $(undefined), $(false)
if (!selector) {
return this;
}
// Method init() accepts an alternate rootjQuery
// so migrate can support jQuery.sub (gh-2101)
root = root || rootjQuery;
// Handle HTML strings
if (typeof selector === "string") {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
…
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
return (context || root).find(selector);
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor(context).find(selector);
}
// HANDLE: $(DOMElement)
} else if (selector.nodeType) {
this[0] = selector;
this.length = 1;
return this;
// HANDLE: $(function)
// Shortcut for document ready
} else if (isFunction(selector)) {
return root.ready !== undefined ? root.ready(selector) :
// Execute immediately if ready is not present
selector(jQuery);
}
return jQuery.makeArray(selector, this);
};
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
// HANDLE: $(#id)
} else {
elem = document.getElementById(match[2]);
if (elem) {
// Inject the element directly into the jQuery object
this[0] = elem;
this.length = 1;
}
return this;
}
28. var rootJquery,
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
// Shortcut simple #id case for speed
rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]+))$/,
init = jQuery.fn.init = function( selector, context, root ) {
var match, elem;
// HANDLE: $(""), $(null), $(undefined), $(false)
if (!selector) {
return this;
}
// Method init() accepts an alternate rootjQuery
// so migrate can support jQuery.sub (gh-2101)
root = root || rootjQuery;
// Handle HTML strings
if (typeof selector === "string") {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
…
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
return (context || root).find(selector);
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor(context).find(selector);
}
// HANDLE: $(DOMElement)
} else if (selector.nodeType) {
this[0] = selector;
this.length = 1;
return this;
// HANDLE: $(function)
// Shortcut for document ready
} else if (isFunction(selector)) {
return root.ready !== undefined ? root.ready(selector) :
// Execute immediately if ready is not present
selector(jQuery);
}
return jQuery.makeArray(selector, this);
};
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
// HANDLE: $(#id)
} else {
elem = document.getElementById(match[2]);
if (elem) {
// Inject the element directly into the jQuery object
this[0] = elem;
this.length = 1;
}
return this;
}
Sem nome!
29. var handleHTMLStrings = function (selector, context, root) {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
// ...
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
// ...
}
return this;
// HANDLE: $(#id)
} else {
// ...
}
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
// ...
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
// ...
}
}
Sem sentido!
30. var handleHTMLStrings = function (selector, context, root) {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
// ...
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
// ...
}
return this;
// HANDLE: $(#id)
} else {
// ...
}
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
// ...
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
// ...
}
}
31. var handleHTMLStringsAndElementIds = function (selector, context, root) {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
// ...
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
// ...
}
return this;
// HANDLE: $(#id)
} else {
// ...
}
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
// ...
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
// ...
}
}
Honesto!
32. var handleHTMLStringsAndElementIds = function (selector, context, root) {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
// ...
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
// ...
}
return this;
// HANDLE: $(#id)
} else {
// ...
}
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
// ...
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
// ...
}
}
33. var handleHTMLStringsAndElementIdsAndCSSSelectors = function (selector, context, root) {
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [null, selector, null];
} else {
match = rquickExpr.exec( selector );
}
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
// ...
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
// ...
}
return this;
// HANDLE: $(#id)
} else {
// ...
}
// HANDLE: $(expr, $(...))
} else if (!context || context.jquery) {
// ...
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
// ...
}
}
Honesto e
completo!
37. handleHTMLStringsAndElementIdsAndCSSSelectors = function (selector, context, root)
handleHTMLStrings = function (selector, context, root)
handleElementIds = function (selector, context, root)
handleCSSSelectors = function (selector, context, root)
38. handleHTMLStringsAndElementIdsAndCSSSelectors = function (selector, context, root)
handleHTMLStrings = function (selector, context, root)
handleElementIds = function (selector, context, root)
handleCSSSelectors = function (selector, context, root)
39. var handleHTMLStrings = function (match, context, root) {
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
}
}
}
Sem sentido?
40. Características de bons nomes de métodos
• Use verbos*;
• Sem abreviações;
• Conciso (mas, não muito!);
• Use perguntas quando o método retornar um boolean (isEmpty(), canDo());
• Não use “And” e “Or” nos seus nomes;
• Não deixe o nome redundante com o argumento
($list->addItem($item));
• Não deixe o nome redundante com quem chama
($list->addToList($item));
41. var buildFromHTMLString = function (match, context, root) {
// Match html or make sure no context is specified for #id
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
}
}
}
42. Temos um bom nome?
• Use verbos* √
• Sem abreviações √
• Conciso (mas, não muito!) √
• Use perguntas quando o método retornar um boolean (isEmpty(), canDo()) √
• Não use “And” e “Or” nos seus nomes √
• Não deixe o nome redundante com o argumento √
• Não deixe o nome redundante com quem chama √
43. var fromHTMLString = function (match, context) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
}
}
44. var fromHTMLString = function (match, context) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
context = context instanceof jQuery ? context[0] : context;
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge(this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// Properties of context are called as methods if possible
if (isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
}
}
45. Características de bons nomes de variáveis
• Sem abreviações;
• Conciso (mas, não muito!);
• Use perguntas quando o método retornar um boolean (isEmpty, canDo);
• Não use “And” e “Or” nos seus nomes;
46. var fromHTMLString = function (source, context) {
if (source) {
context = context instanceof jQuery ? context[0] : context;
var runScriptsForBackCompat = true
var isNode = context && context.nodeType;
var contextDocument = isNode ? context.ownerDocument || context : document;
jQuery.merge(this, jQuery.parseHTML(source, contextDocument, runScriptsForBackCompat));
var isSingleTagWithoutAttributes = rsingleTag.test(source)
var isAttributesSuperSet = jQuery.isPlainObject(context);
if (isSingleTagWithoutAttributes && isAttributesSuperSet) {
for (attributeName in context) {
// Properties of context are called as methods if possible
if (isFunction(this[attributeName])) {
this[attributeName](context[attributeName]);
// ...and otherwise set as attributes
} else {
this.attr(attributeName, context[attributeName]);
}
}
}
return this;
}
}
47. var fromHTMLString = function (source, context) {
if (source) {
context = context instanceof jQuery ? context[0] : context;
var runScriptsForBackCompat = true
var isNode = context && context.nodeType;
var contextDocument = isNode ? context.ownerDocument || context : document;
jQuery.merge(this, jQuery.parseHTML(source, contextDocument, runScriptsForBackCompat));
var isSingleTagWithoutAttributes = rsingleTag.test(source)
var isAttributesSuperSet = jQuery.isPlainObject(context);
if (isSingleTagWithoutAttributes && isAttributesSuperSet) {
for (attributeName in context) {
// Properties of context are called as methods if possible
if (isFunction(this[attributeName])) {
this[attributeName](context[attributeName]);
// ...and otherwise set as attributes
} else {
this.attr(attributeName, context[attributeName]);
}
}
}
return this;
}
}
48. Características de bons nomes de classes
• Use substantivos e adjetivos*;
• Não use muitos adjetivos (AbstractFactoryPatternBase);
• Não use “Manager”, “Helper” e “Data” nos seus nomes;
• Não use Sufixos do seu namespace (Service, Factory, Iterator)
• Evite usar “er”, “or”, “tion”, “sion” (ObjectFinder, DataProcessor, Conversion,
DataManipulation)
51. var HTMLCreationContext = function (elementOrAttributes) {
this.elementOrAttributes = elementOrAttributes;
}
HTMLCreationContext.prototype = {
isNode: function () {
return (this.elementOrAttributes && this.elementOrAttributes.nodeType);
},
getOwnerDocument: function () {
if (this.isNode) {
return this.elementOrAttributes.ownerDocument || this.elementOrAttributes;
}
return document;
},
getAttributesSuperSet: function () {
if (jQuery.isPlainObject(this.elementOrAttributes)) {
return this.elementOrAttributes;
}
return {};
},
getMergeContext: function () {
if (this.elementOrAttributes instanceof jQuery) {
return this.elementOrAttributes[0];
}
return this.elementOrAttributes;
}
}
52. var HTMLCreationContext = function (elementOrAttributes) {
this.elementOrAttributes = elementOrAttributes;
}
HTMLCreationContext.prototype = {
isNode: function () {
return (this.elementOrAttributes && this.elementOrAttributes.nodeType);
},
getOwnerDocument: function () {
if (this.isNode) {
return this.elementOrAttributes.ownerDocument || this.elementOrAttributes;
}
return document;
},
getAttributesSuperSet: function () {
if (jQuery.isPlainObject(this.elementOrAttributes)) {
return this.elementOrAttributes;
}
return {};
},
getMergeContext: function () {
if (this.elementOrAttributes instanceof jQuery) {
return this.elementOrAttributes[0];
}
return this.elementOrAttributes;
}
}
53. var fromHTMLString = function (source, context) {
if (source) {
var creationContext = new HTMLCreationContext(context);
var runScriptsForBackCompat = true
jQuery.merge(this, jQuery.parseHTML(
source,
creationContext.getOwnerDocument(),
runScriptsForBackCompat
));
var isSingleTagWithoutAttributes = rsingleTag.test(source)
if (isSingleTagWithoutAttributes) {
var attributes = creationContext.getAttributesSuperSet();
for (attributeName in attributes) {
// Properties of context are called as methods if possible
if (isFunction(this[attributeName])) {
this[attributeName](context[attributeName]);
// ...and otherwise set as attributes
} else {
this.attr(attributeName, context[attributeName]);
}
}
}
return this;
}
}
54.
55. Concluindo…
1. Procure por lugares com mais de um nível de identação
2. Extraia e dê nome para o que fizer sentido
3. Descreva o que o método realmente faz, sem vergonha, seja honesto!
4. Vá diminuindo o nome do método extraindo suas responsabilidades
5. Excesso de métodos privados para um dado contexto: Uma nova classe!
6. Procure na documentação ou fale com um amiguinho para descrever
o problema de domínio resolvido
7. Seja feliz!