O padrão de design da estratégia é frequentemente considerado um substituto para funções de primeira classe em idiomas que não as possuem.
Por exemplo, digamos que você desejasse passar a funcionalidade para um objeto. Em Java, você teria que passar no objeto outro objeto que encapsula o comportamento desejado. Em um idioma como Ruby, você passaria a própria funcionalidade na forma de uma função anônima.
No entanto, eu estava pensando sobre isso e decidi que talvez a Strategy ofereça mais do que uma simples função anônima.
Isso ocorre porque um objeto pode conter um estado que existe independentemente do período em que o método é executado. No entanto, uma função anônima por si só pode conter apenas um estado que deixa de existir no momento em que a função termina a execução.
Em uma linguagem orientada a objetos que suporta funções de primeira classe, o padrão de estratégia tem alguma vantagem sobre o uso de funções?
fonte
Respostas:
Quando a linguagem suporta referências à função ( Java faz desde a versão 8 ), essas geralmente são uma boa alternativa para estratégias, porque geralmente expressam a mesma coisa com menos sintaxe. No entanto, existem alguns casos em que um objeto real pode ser útil.
Uma interface de estratégia pode ter vários métodos. Vamos usar uma interface
RouteFindingStragegy
como exemplo, que engloba diferentes algoritmos de localização de rotas. Poderia declarar métodos comoRoute findShortestRoute(Node start, Node destination)
boolean doesRouteExist(Node start, Node destination)
Route[] findAllPossibleRoutes(Node start, Node destination)
Route findShortestRouteToClosestDestination(Node start, Node[] destinations)
Route findTravelingSalesmanRoute(Node[] stations)
que então seriam todos implementados pela estratégia. Alguns algoritmos de localização de rota podem permitir otimizações internas para alguns desses casos de uso e outros não, portanto o implementador pode decidir como implementar cada um desses métodos.
Outro caso é quando a estratégia tem um estado interno. Certamente, em alguns idiomas, os fechamentos podem ter um estado interno, mas quando esse estado interno se torna muito complexo, muitas vezes fica mais elegante promover o fechamento para uma classe de pleno direito.
fonte
Não é verdade que uma função anônima possa manter apenas o estado que deixa de existir quando a função termina a execução.
Veja o seguinte exemplo no Common Lisp:
Esta função pega uma lista de strings e precede um contador para cada elemento da lista. Então, por exemplo, invocando
dá
A função
number-strings
usa internamente uma função anônima com uma variávelcounter
que mantém o estado (o valor atual do contador) que é reutilizado toda vez que a função é chamada.Em geral, você pode pensar em um fechamento como um objeto com apenas um método. Como alternativa, um objeto é uma coleção de fechamentos que compartilham as mesmas variáveis de fechamento. Portanto, não tenho certeza se há casos em que você precisa usar um objeto em vez de um fechamento: eu argumentaria que ambas são maneiras de olhar para o mesmo padrão de perspectivas diferentes.
Em particular, o padrão de estratégia requer um objeto com apenas um método, portanto, um fechamento deve fazer o trabalho. Mas, como Philipp observou em sua resposta, dependendo das circunstâncias (estado complexo) e das linguagens de programação, você pode obter uma solução mais elegante usando objetos.
fonte
let
e depois definir meu fechamento dentro dele. Basicamente, eu teria definido um objeto com um método em tempo real. Em outra linguagem (por exemplo, Java), pode ser mais conveniente (sintaticamente mais simples) definir um objeto apropriado para conter o estado. Então, eu decidiria caso a caso.Só porque dois projetos podem resolver o mesmo problema não significa que eles sejam substituições diretas um do outro.
Se você precisar rastrear o estado em um programa funcional, não modifique uma variável fechada, mesmo que o idioma permita. Você planeja chamar uma função que aceita um estado como argumento e retorna o novo estado como seu valor de retorno.
Sua arquitetura terá uma aparência muito diferente, mas você alcançará o mesmo objetivo. Não tente forçar os padrões de um paradigma diretamente sobre o outro.
fonte
Estratégia é um conceito , uma receita útil para resolver um problema recorrente recorrente. Não é uma construção de linguagem, nem é sobre qualquer forma de implementação . Um fechamento pode ser usado para implementar a estratégia em um dia e o Observer no dia seguinte.
O termo Estratégia é muito útil em conversas com outros programadores para expressar de forma concisa sua intenção. Não há nada de mágico nisso.
fonte