Eu quero perguntar - estou aprendendo lentamente o jQuery.
O que vejo é um exemplo exato de um antipadrão de Objeto de Deus . Basicamente, tudo vai para a $
função, seja ela qual for.
Estou certo e o jQuery é realmente um exemplo desse anti-padrão?
jquery
anti-patterns
Karel Bílek
fonte
fonte
$
função ou umjQuery
objeto.Respostas:
Para responder a essa pergunta, vou fazer uma pergunta retórica sobre outra estrutura que possui propriedade semelhante aos elementos DOM que o jQuery manipula, que é o bom e antigo iterador. A questão é:
Quantas operações você precisa em um iterador simples?
A pergunta pode ser respondida facilmente, analisando qualquer API Iterator em um determinado idioma. Você precisa de 3 métodos:
É tudo o que você precisa. Se você puder executar essas 3 operações, poderá percorrer qualquer sequência de elementos.
Mas isso não é apenas o que você geralmente quer fazer com uma sequência de elementos, é? Você geralmente tem uma meta de nível muito mais alto a alcançar. Você pode querer fazer algo com todos os elementos, filtrá-los de acordo com alguma condição ou com um de vários outros métodos. Consulte a interface IEnumerable na biblioteca LINQ no .NET para obter mais exemplos.
Você vê quantos existem? E isso é apenas um subconjunto de todos os métodos que eles poderiam ter colocado na interface IEnumerable, porque você geralmente os combina para atingir objetivos ainda mais altos.
Mas aqui está a reviravolta. Esses métodos não estão na interface IEnumerable. São métodos simples de utilidade que, na verdade, usam um IEnumerable como entrada e fazem algo com ele. Portanto, enquanto na linguagem C # parece haver vários métodos na interface IEnumerable, IEnumerable não é um objeto divino.
Agora, de volta ao jQuery. Vamos fazer essa pergunta novamente, desta vez com um elemento DOM.
Quantas operações você precisa em um elemento DOM?
Novamente, a resposta é bem direta. Todos os métodos que você precisa são métodos para ler / modificar os atributos e os elementos filhos. É sobre isso. Tudo o resto é apenas uma combinação dessas operações básicas.
Mas quanto de nível superior você gostaria de fazer com os elementos DOM? Bem, o mesmo que um iterador: um bilhão de coisas diferentes. E é aí que entra o jQuery. O jQuery, em essência, fornece duas coisas:
Se você escolher o formato açucarado, perceberá que o jQuery poderia facilmente ter sido escrito como várias funções que selecionam / modificam elementos DOM. Por exemplo:
... poderia ter sido escrito como:
Semântica é exatamente a mesma coisa. No entanto, o primeiro formulário tem a grande vantagem de que a ordem da esquerda para a direita das instruções segue a ordem em que as operações serão executadas. A segunda começa no meio, o que dificulta a leitura do código se você combinar muitas operações.
Então o que tudo isso significa? Esse jQuery (como LINQ) não é o antipadrão de objetos de Deus. Em vez disso, é um caso de um padrão muito respeitado chamado Decorator .
Mas, novamente, o que dizer da substituição de
$
fazer todas essas coisas diferentes? Bem, isso é apenas açúcar sintático, na verdade. Todas as chamadas$
e seus derivados$.getJson()
são coisas completamente diferentes que compartilham nomes semelhantes, para que você possa sentir imediatamente que eles pertencem ao jQuery.$
realiza uma e apenas uma tarefa: permite que você tenha um ponto de partida facilmente reconhecível para usar o jQuery. E todos esses métodos que você pode chamar em um objeto jQuery não são um sintoma de um objeto deus. Eles são simplesmente funções utilitárias diferentes, cada uma executando uma única coisa em um elemento DOM passado como argumento. A notação .dot está aqui apenas porque facilita a escrita do código.fonte
Não - a
$
função é sobrecarregada apenas por três tarefas . Tudo o resto são funções filho que apenas o utilizam como um espaço para nome .fonte
Math
. Como não há espaço para nome incorporado no JS, eles apenas usam um objeto para isso. Embora eu não tenha certeza de qual seria a alternativa? Coloque todas as funções e propriedades no espaço para nome global?A principal função jQuery (por exemplo
$("div a")
) é essencialmente um método de fábrica que retorna uma instância do tipo jQuery que representa uma coleção de elementos DOM.Essas instâncias do tipo jQuery têm um grande número de métodos de manipulação de DOM disponíveis, que operam nos elementos DOM representados pela instância. Embora isso possa ser considerado uma classe que é muito grande, ele realmente não se encaixa no padrão de Objeto de Deus.
Por fim, como menciona Michael Borgwardt, também há um grande número de funções utilitárias que usam $ como um espaço para nome e são apenas tangencialmente relacionadas aos objetos jQuery da coleção DOM.
fonte
$
não é um objeto, é um espaço para nome.Você chamaria java.lang de um objeto god por causa das muitas classes que ele contém? É uma sintaxe absolutamente válida para chamar
java.lang.String.format(...)
, muito semelhante em forma a chamar qualquer coisa no jQuery.Um objeto, para ser um objeto divino, deve ser um objeto apropriado em primeiro lugar - contendo dados e inteligência para agir sobre os dados. O jQuery contém apenas os métodos.
Outra maneira de ver: uma boa medida de quanto de um objeto deus é um objeto é a coesão - coesão mais baixa significa mais um objeto de deus. A coesão diz que grande parte dos dados é usada por quantos dos métodos. Como não há dados no jQuery, você faz as contas - todos os métodos usam todos os dados; portanto, o jQuery é altamente coeso, não sendo, portanto, um objeto divino.
fonte
Benjamin me pediu para esclarecer minha posição, por isso editei meu post anterior e acrescentei mais pensamentos.
Bob Martin é o autor de um grande livro intitulado como Código Limpo. Nesse livro, há um capítulo (Capítulo 6.) chamado Objetos e estruturas de dados, que ele discute as diferenças mais importantes entre objetos e estruturas de dados e afirmações que precisamos escolher entre eles, porque misturá-los é uma péssima idéia.
Eu acho que o DOM é um exemplo desses híbridos de objetos e estrutura de dados. Por exemplo, por DOM, escrevemos códigos como este:
O DOM deve ser claramente uma estrutura de dados em vez de um híbrido.
A estrutura do jQuery é uma série de procedimentos, que podem selecionar e modificar uma coleção de nós DOM e fazer muitas outras coisas. Como Laurent apontou em seu post, o jQuery é algo assim:
Os desenvolvedores do jQuery mesclaram todos esses procedimentos em uma única classe, responsável por todos os recursos listados acima. Por isso, viola claramente o Princípio da Responsabilidade Única e, portanto, é um objeto divino. A única coisa que não quebra nada, porque é uma única classe independente que funciona em uma única estrutura de dados (a coleção de nós DOM). Se adicionarmos subclasses jQuery ou outra estrutura de dados, o projeto entrará em colapso muito rápido. Portanto, acho que não podemos falar sobre oo pelo jQuery, é mais processual do que ooo, apesar de definir uma classe.
O que Laurent afirma é um absurdo completo:
O padrão Decorator visa adicionar novas funcionalidades mantendo a interface e não modificando as classes existentes. Por exemplo:
Você pode definir 2 classes que implementam a mesma interface, mas com uma implementação completamente diferente:
Se você tiver métodos que usam apenas a interface comum, poderá definir um ou mais decoradores em vez de copiar e colar o mesmo código entre A e B. Você pode usar esses decoradores mesmo em uma estrutura aninhada.
Portanto, você pode substituir as instâncias originais pelas instâncias do decorador no código de nível de abstração mais alto.
A conclusão de que o jQuery não é um decorador de nada, porque não implementa a mesma interface que Array, NodeList ou qualquer outro objeto DOM. Ele implementa sua própria interface. Os módulos também não são utilizados como decoradores, eles simplesmente substituem o protótipo original. Portanto, o padrão Decorator não é usado em toda a lib do jQuery. A classe jQuery é simplesmente um grande adaptador que nos permite usar a mesma API por muitos navegadores diferentes. De uma perspectiva completa, é uma bagunça completa, mas isso realmente não importa, funciona bem e nós a usamos.
fonte