“Método de Fábrica é uma especialização do Método de Modelo”. Quão?

10

Semelhanças e diferenças entre os dois:

Método de modelo

  • Confia na herança.
  • Define as etapas de um algoritmo e deixa a tarefa de implementá-las nas subclasses.

Método de fábrica

  • Confia na herança.
  • Uma superclasse define uma interface para criar um objeto. As subclasses decidem qual classe concreta instanciar.

Os dois lado a lado:

insira a descrição da imagem aqui

Não sei ao certo o que a frase "Método de Fábrica é uma especialização de Método de Modelo" (está no livro Head First Design Patterns ). Em Beveragenós temos o método prepareque é finale define uma série de etapas. Em PizzaStorenós temos um método que é abstract, e subclasses o redefinem. Como o último é uma especialização do primeiro?

Maria Ines Parnisari
fonte
5
Eu vejo muitos votos negativos neste post da polícia de padrões. Realmente não há razão para isso; agora você tem três pessoas que dizem que a frase provavelmente não é recomendada. Nota aos leitores deste post: não acredite em tudo que lê em um livro ou online.
Robert Harvey

Respostas:

6

Em Beveragenós temos o método ("template") prepareque chama alguns métodos abstratos como boilWater, brewetc. , que são implementados nas subclasses. Não é essencialmente para o padrão ter o método de modelo localizado na classe base, ele pode estar em qualquer outro lugar, desde que os métodos abstratos sejam públicos. Mas é essencialmente que existem os métodos abstratos que devem ser substituídos e preencherão as lacunas no "modelo de algoritmo".

O método factory também é sobre uma classe na qual os métodos abstratos são substituídos; um ponto principal é que o chamador desse método não precisa saber o tipo exato do objeto criado. Note que em PizzaStore, o método abstrato createPizzadeve ser chamado em algum lugar de - digamos um método createLotsOfPizza.

Isso o torna um método de modelo, onde as etapas específicas do "algoritmo para criar pizzas" são as lacunas a serem preenchidas. Agora é provavelmente apenas um uso impreciso de palavras, dizendo "o padrão de método de fábrica" ​​é um caso especial do padrão "método de modelo". Especialmente os "métodos de fábrica" ​​não são "métodos de modelo", no entanto, eles podem ser chamados de um método de modelo. Para ser mais preciso, podemos dizer

"o padrão de método de fábrica é normalmente usado em conjunto com um caso especial do padrão de método de modelo"

e acho que é isso que os autores desse livro querem expressar.

Doc Brown
fonte
2

Eu acho que "Factory Method é uma especialização do Template Method" é uma má caracterização. Acredito que seria mais preciso dizer que o padrão do Método do Modelo é apenas uma variação do padrão do Método da Fábrica.

Além disso, afirmo que o padrão do Método do Modelo não é realmente um padrão (no sentido da Gangue dos Quatro), uma vez que surge naturalmente através da herança e da substituição do método. Você pode ver que, no diagrama acima para o Modelo Padrão, as classes descendentes simplesmente substituem os métodos na classe base por seu próprio comportamento.

No geral, os Padrões de Software (da variedade Gang of Four) são realmente apenas soluções alternativas para deficiências nas linguagens de programação, e o Template Template apenas reafirma de que linguagens orientadas a objetos já são nativamente capazes.

Robert Harvey
fonte
Se você estiver usando uma definição de um padrão de design que faça com que o Template Method não seja um padrão de design, acho que sua definição está errada. Os padrões de design são idéias abstratas que transmitem relacionamentos entre diferentes partes do seu código e não têm nada a ver com o idioma em que são implementados. Os padrões de design não são detalhes de implementação, são descrições que podem ser usadas em alto nível em para comunicar as decisões de design que foram tomadas em relação a parte de um sistema.
Jules
Mais especificamente, o Método do modelo é uma maneira específica de usar herança que é útil em algumas circunstâncias, mas é claramente uma decisão de design, pois existem outras maneiras de atingir o mesmo objetivo (o mesmo efeito pode ser alcançado, por exemplo, usando agregação, nesse caso, provavelmente seria considerado uma instância do padrão de estratégia). Dado que uma decisão está sendo tomada, um nome é importante para nos permitir falar sobre essa decisão e, onde temos um nome como esse, é um padrão de design.
Jules
1

Eu diria que o Head First está simplesmente errado nessa caracterização.

A Wikipedia define o Método do modelo como:

Na engenharia de software, o padrão do método de modelo é um padrão de design comportamental que define o esqueleto do programa de um algoritmo em uma operação, adiando algumas etapas para as subclasses.

(Faz referência ao GoF para isso.)

E o Método de Fábrica é definido como:

Na programação baseada em classes, o padrão de método de fábrica é um padrão de criação que usa métodos de fábrica para lidar com o problema de criar objetos sem precisar especificar a classe exata do objeto que será criado.

Não há sobreposição entre os dois, exceto que em C ++, a herança é uma parte essencial de ambos. No entanto, em linguagens que fazem uma distinção entre herança de implementação ( extendsem Java) e implementação de interface ( implementsem Java), mesmo essa semelhança não existe, pois a implementação da interface é suficiente para o método de fábrica, mas não para o modelo. E em C ++, a herança pura de implementação (sem a herança da interface, ou seja, herança privada ou CRTP) pode ser usada para o primeiro, mas não para o último.

E além disso? Um é um padrão de design comportamental, o outro é um padrão criacional. Um descreve um esboço de uma operação, com algumas partes importantes deixadas de fora para serem preenchidas por subclasses especializadas; o outro especifica um contrato muito simples, deixando toda a implementação para instâncias concretas. Eles são completamente distintos.

Na minha opinião, a linha citada está simplesmente errada. Ou é um erro gritante no livro ou (menos provável) está fora de contexto e deve ser interpretado de maneira diferente.

Sebastian Redl
fonte
Eu acho que a afirmação não é claramente "errada", é apenas um uso desleixado das palavras. Veja minha edição.
Doc Brown