Comecei a pesquisar recentemente em Design Patterns, e uma coisa que estou codificando se adequaria perfeitamente ao padrão Strategy, exceto por uma pequena diferença.
Essencialmente, alguns (mas não todos) dos meus algoritmos precisam de um ou dois parâmetros extras passados para eles.
Então eu vou precisar
- passar a eles um parâmetro extra quando eu invocar o método de cálculo
ou
- armazená-los como variáveis dentro da classe ConcreteAlgorithm e poder atualizá-los antes que eu chame o algoritmo.
Existe um padrão de design para essa necessidade / Como eu poderia implementar isso enquanto seguia o Padrão de Estratégia?
Eu considerei passar o objeto cliente para todos os algoritmos e armazenar as variáveis lá, usando-o somente quando o algoritmo específico precisar dele. No entanto, acho que isso é difícil de manejar e derrota o objetivo do padrão de estratégia.
Só para esclarecer, estou implementando em Java e, portanto, não tenho o luxo de parâmetros opcionais (o que resolveria isso muito bem).
fonte
Respostas:
Samuel, é possível encapsular o parâmetro que cada uma das estratégias leva em uma classe comum e depois estender essa classe Parameter comum para adicionar mais comportamento do que algumas de suas estratégias especificamente precisam?
Por exemplo
E então, defina a hierarquia da estratégia como:
chame a estratégia acima como:
myNormalStrategyInstance.myStrategyMethod(strategyParameter);
chame a estratégia acima, passando a
SpecialStrategyParameter
instância como:mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);
Atualize se algo não estiver claro. Será um prazer explicar / esclarecer.
fonte
StrategyParameter
conter todos os parâmetros possíveis, como um DTO. Algumas implementações da estratégia podem ignorá-las. Em alguns casos, essa é a melhor abordagem. O contexto é o rei para esse tipo de problema.Você precisa esclarecer sua estratégia .
Tudo depende de como você usa seus algoritmos. Para que sua classe cliente use implementações de estratégias diferentes de forma intercambiável, todas elas precisam ter uma abstração comum . Se eles não seguem a mesma interface, talvez você precise de abstrações diferentes .
Eu usei estratégias configuráveis antes, onde você parametriza as classes concretas na construção:
Agora, alguém ainda precisa criar uma instância dessa classe e passá-la ao seu cliente. Mas seu cliente ainda precisa apenas conhecer a
Strategy
interface.Também funciona se o seu método de estratégia usa parâmetros, mas seu cliente conhece esses parâmetros e os passa para todas as implementações com as quais trabalha.
fonte
Desde que a assinatura seja definida claramente na interface, ela ainda está em conformidade com o padrão de estratégia.
Os padrões escritos são a forma absoluta mais simples que ainda exibe o comportamento esperado, para que você possa embelezá-los desde que mantenha a intenção original. Isso, é claro, pressupõe que você queira seguir o padrão. Não faz sentido usar um padrão se ele não se encaixar, ou apenas porque está lá, mas no seu caso, acho que você está bem.
fonte
estendendo-se à resposta acima fornecida pelo peakit - você pode usar a abstração. Estou usando o código do peakit aqui -
Interface MyStrategy { resumo vazio myStrategyMethod (parâmetro StrategyParameter); }
classe MyNormalStrategy estende MyStrategy {substituição pública anula myStrategyMethod (parâmetro StrategyParameter) {// implementa a lógica aqui}}
classe MySpecializedStrategy estende MyStrategy {substituição pública anula myStrategyMethod (parâmetro StrategyParameter, ExtraStrategyParameter extraParameter) {// implementa a lógica aqui} }
Se entendi sua pergunta corretamente, você queria passar um parâmetro extra para certos algoritmos, certo? Informe-me se é isso que você estava procurando?
fonte
Se você olhar para o livro Padrões de design, não é errado, por si só, que exista algum SimpleStrategy que use menos ou nenhum dos parâmetros passados ou que os parâmetros sejam um multiplicador de tamanho único / multiplicador menos comum. A escolha do design aqui é se isso prejudica você em termos de processamento extra que acaba não sendo usado.
fonte