Por que os padrões de design não são adicionados às construções de idiomas?

11

Recentemente, conversei com um colega que mencionou que sua empresa estava trabalhando para adicionar o padrão de design MVC como uma extensão PHP.

Ele explicou que eles escreveram o código C para adicionar Controllers, Models and Viewsàs construções de linguagem para aumentar o desempenho.

Agora eu sei que o MVC é um padrão de design de arquitetura amplamente usado em aplicativos da Web, mas ainda preciso encontrar idiomas que tenham uma construção de idioma para os Controladores, por exemplo.

A integração de padrões de design em uma linguagem IMHO pode enfatizar a importância de um bom design de OO.

Então, por que os padrões de design mais usados ​​(MVC, Factory, Strategy, ... etc.) São adicionados às construções de linguagem?

Se a pergunta parecer muito ampla, você poderá limitar a pergunta apenas ao PHP.

Editar:

Não estou sugerindo que é preciso usar um padrão de design ao desenvolver um projeto. Na verdade, eu promovo a metodologia para mantê-lo simples, desde que funcione.

Songo
fonte
19
Existe uma escola de pensamento que diz que ter muitos padrões é um cheiro de linguagem. Certamente muitos padrões no livro GO4 desaparecem ou se tornam um liner 1 no Lisp.
Zachary K
5
"Construir fábricas é 100% garantido em qualquer projeto." Então você trabalhou em projetos ruins. Enquanto a fábrica é um padrão útil, está longe de ser garantida. Qualquer OOP tem padrão de fábrica. É chamado de construtor.
Euphoric
9
Sou bastante cético em relação à coisa OO em geral. Pode haver uma ideia de promover a reutilização, sim, mas simplesmente não funciona. E, depois de ter algumas ferramentas realmente poderosas disponíveis, como metaprogramação, funções de alta ordem, sistemas de tipos poderosos, módulos etc., você poderá expressar todos os padrões de design de OO à medida que a nova linguagem construa facilmente - mas você não quero fazer isso, porque com tudo isso, você não precisará mais de nenhum OO.
SK-logic
2
Como isso significa adicionar recursos, na linguagem de uso geral, você não deseja um idioma com dois mil recursos, porque todas essas sintaxes e sutis interações cruzadas entre os recursos não cabem na sua cabeça. Em vez disso, você deseja um idioma com um conjunto mínimo de recursos que possam acomodar muitos padrões de design de maneira sucinta. Se um padrão de design puder ser escrito em termos de recursos de idioma existentes com uma sintaxe não muito ruim, o custo de adicionar o novo recurso é muito mais alto e complicaria desnecessariamente o idioma.
Lie Ryan
5
Há também uma escola de pensamento (à qual eu pertenço) que diz que os padrões de design são apenas soluções alternativas para deficiências em um idioma. A seus olhos, todos os padrões de design existentes não existiriam na linguagem perfeita; mas, considerando que os idiomas mais populares estão longe de serem perfeitos, estamos presos a essas soluções alternativas. (Exemplo)
BlueRaja - Danny Pflughoeft

Respostas:

20

Os padrões de design são adicionados às construções de linguagem o tempo todo. Já ouviu falar do padrão de design de chamadas sub - rotineiras ? Não? Nem eu. Isso porque as chamadas de sub-rotina, que eram um padrão de design no início dos anos 50, foram adicionadas aos idiomas praticamente instantaneamente. Atualmente, eles estão presentes nos conjuntos de instruções de código de máquina das CPUs.

E o Padrão de Design do Loop For ? O Padrão de Design do Loop While ? O padrão de design do switch ? O padrão de design de objetos ? O padrão de design de classe ? Todos estes foram adicionados a alguns idiomas.

Jörg W Mittag
fonte
Na verdade, padrões de design variados para chamadas de sub-rotina eram comuns (no código de montador e de máquina, pelo menos) até o final dos anos 50, início dos anos 60 e também eram exibidos, por exemplo, no M6800 (o de 8 bits). Procure por Wheeler jumpou Modified Wheeler jump.
Vatine 18/07/12
A ausência de construir tal na TI-83 Pluslinguagem básica levou a um padrão de volta semelhante quando eu estava aprendendo a programa em torno de 2001.
Izkata
12

Alguns deles são. Por exemplo, iteradores são recursos de idiomas em muitos idiomas e em suas bibliotecas padrão (oi, foreach e yield return). O Observer também está frequentemente presente na forma de eventos (não no PHP - você mesmo precisa gerenciar a assinatura de retorno de chamada). O comando é o principal recurso do WPF.

Muitos dos outros não se beneficiariam realmente do suporte ao idioma (e tornariam o idioma mais complicado) - como você simplificaria os Controladores se pudesse projetar um recurso de idioma para eles? Como classes, eles se beneficiam de toda a infraestrutura já presente para dar suporte às classes - você pode instancia-las, distribuí-las e, por exemplo, testá-las como qualquer outro objeto.

O único componente do MVC que a IMO poderia se beneficiar de algum tipo de suporte a idiomas é o View (com algum mecanismo oficial de modelagem) - e no PHP já é suportado - você é capaz de criar e carregar dinamicamente scripts PHP (que geralmente são algum tipo de pré-processamento usado como modelo).

O mesmo se aplica ao método de fábrica - como você simplificaria isso, se pudesse ter qualquer tipo de recurso de idioma que desejasse? Um recurso que falta a algumas linguagens (como C ++) é a capacidade de construir objetos a partir desse nome de tipo, mas a maioria das linguagens de nível superior pode fazer isso (e nem é necessário criar métodos úteis de fábrica). Fora isso, tudo o que você precisa é ser capaz de criar um método que instancia, devolve e objeta.

Matěj Zábský
fonte
10
Até a orientação a objetos pode ser pensada como um padrão específico que foi considerado útil e, portanto, incorporado em vários idiomas. Em geral, a presença de um padrão é um indicador da falta de um recurso de idioma.
187 Andrea Andrea
7

Alguns padrões de design são realmente adicionados como construções de linguagem - eles simplesmente não são identificados como tal porque as pessoas começam a considerá-los como "sintaxe" uma vez incorporadas. O tratamento de exceções em Java é um bom exemplo - muitas pessoas codificariam algo semelhante explicitamente como padrão de design, se não fizesse parte da sintaxe principal.

Mas, para focar na pergunta - há muitas razões pelas quais você não deseja adicionar muitos padrões de design a um idioma:

  • Não é necessário adicioná-los como construções de linguagem - todos os padrões de design podem ser implementados de outras maneiras
  • Isso complicaria o idioma - essa é uma péssima idéia, pois dificulta o aprendizado do idioma, dificulta a escrita de compiladores e ferramentas
  • Existem abordagens alternativas de implementação para muitos padrões de design. Escolher uma abordagem e abençoá-la como parte da linguagem principal provavelmente levaria as pessoas a usar essa abordagem em detrimento de outras (o que pode ser muito melhor em algumas circunstâncias)
  • O excesso de confiança nos padrões de design é provavelmente uma má idéia em qualquer caso - os designers de linguagem provavelmente percebem que não deveriam encorajá-los ainda mais.

Além disso, se você usar uma linguagem suficientemente poderosa com recursos de metaprogramação (por exemplo, um Lisp), torna-se relativamente simples estender a linguagem você mesmo para implementar qualquer padrão de design. Você não precisa de nenhum padrão no idioma principal se for fácil adicionar o seu próprio com uma macro de 5 linhas.

Mikera
fonte
4

Por que os padrões de design mais usados ​​(MVC, Factory, Strategy, ... etc.) São adicionados às construções de linguagem?

A maioria desses padrões pode ser implementada na maioria das linguagens de programação sem suporte linguístico específico. Tomemos, por exemplo, o MVC em Java:

  • Você pode codificá-lo diretamente.
  • Você pode implementá-lo usando um gerador de aplicativos ... e cuidar de muitos outros clichês ao mesmo tempo.
  • Você pode implementá-lo usando as classes da biblioteca "framework".
  • Você pode implementá-lo usando anotações e processamento de anotação estática ou de tempo de execução.

Dadas todas essas opções, há pouco valor em estender diretamente o idioma. E há uma série de "desvantagens":

  • Tenderia a desordenar a sintaxe da linguagem, (sem dúvida) dificultando a vida de programadores iniciantes.
  • Isso tenderia a tornar a especificação de linguagem maior e mais complexa, dificultando os implementadores de linguagem. (E, é claro, quanto maior a especificação, maior a probabilidade de haver erros e inconsistências.)
  • Sempre haverá pressão para adicionar outro padrão ... levando a problemas / preocupações com a estabilidade da linguagem.
  • Ao oferecer suporte a padrões específicos no idioma, você conecta maneiras específicas de suporte aos padrões, o que pode não ser adequado para alguns aplicativos.
Stephen C
fonte
4

Eles são.

As funções eram um padrão de design no código de montagem antes de se tornarem uma construção de linguagem em C.

As funções virtuais eram um padrão de design em C antes de se tornarem uma construção de idioma no C ++.

No entanto, há uma troca. Se o padrão envolver a produção de código padrão (mesmo algumas palavras-chave), isso é uma indicação de que seria um recurso útil da linguagem. Mas se o padrão é simples e claro, por exemplo. C "para (int i = 0; i <10; i ++)", ainda é útil para todos escreverem da mesma maneira, mas não é significativamente maior que "para i = 0 a 10" e tem a vantagem significativa de que é óbvio como alterá-lo para criar um loop um pouco diferente.

Jack V.
fonte
3

Leia o livro da gangue dos quatro e ficará claro que:

  1. Os padrões de design do livro são, na verdade, convenções bem conhecidas de conversas codificadas em outros idiomas OO.
  2. Dessa forma, esses padrões não podem ser incluídos na linguagem OO - seria reimplementar o smalltalk nesses idiomas - é melhor usar o smalltalk diretamente
  3. O motivo pelo qual os padrões de design são úteis é porque eles enfatizam o papel da linguagem usada atualmente e se concentram em outros problemas além da sintaxe. A codificação desses padrões dentro do idioma perderia esse recurso dos padrões de design.
  4. O verdadeiro problema na pergunta acima é que ele perde o ponto de que escrever software não é apenas aprender o idioma. É importante ter distância suficiente do idioma que está fornecendo diretamente e focar nos requisitos atuais.
tp1
fonte
2

Como os padrões de design são implementados perfeitamente bem com o código do usuário. O exemplo dele só aconteceu porque é PHP - mas se você realmente precisasse de desempenho, apenas trabalharia em outra linguagem ou obteria o HipHop ou algo assim.

Os recursos de linguagem são complicados, tanto para especificar quanto para implementar, e não é justificável criar um com o único objetivo de "Os idiomas atuais são X". Você quase não salvaria nenhum código de usuário significativo e por nada.

DeadMG
fonte
0

Eh, pergunta obsoleta, mas eu discordo de muitas respostas, dependendo de onde você define "Design Patterns" no mostrador semântico, incluindo o aceito.

No sentido de livro do GoF Design Patterns, eu diria que depende. O MVC, por exemplo (não é realmente um padrão GoF, mas se encaixa nesse modelo), é totalmente inapropriado para expressar como construções de linguagem para consumo em massa (embora possa fazer sentido para um projeto PHP específico). Como padrão arquitetural, há variações constantes sobre o tema e uma ampla variedade de interpretações perfeitamente legítimas para diferentes circunstâncias (embora muitos se afastem tão longe do MVC, eles provavelmente não deveriam mais chamá-lo de MVC). Por exemplo, na Web, a barreira do http torna um ajuste um tanto estranho, dependendo se você está tentando incluir o lado do cliente (sem dúvida dolorosa) na equação e o que está considerando "a visualização" de uma maneira mais adequadamente estritamente do lado do servidor.

O iterador, por outro lado, é um conceito altamente geral que pode ser aplicado de várias maneiras a uma ampla variedade de construções.

Onde se deve definir se algo pertence a um design de linguagem principal, mesmo em uma linguagem específica da Web do servidor, IMO, é o ponto em que algo ultrapassa a linha, facilitando a execução de um número incalculável de coisas mais facilmente do que fazer uma coisa excessivamente específica, mas amplamente implementada, como um padrão de arquitetura para você.

Erik Reppen
fonte