Objective-C categorias == visitante padrão?
-
20-09-2019 - |
Pergunta
Você diria que o objective-C categorias são uma implementação do o visitante padrão de design?
Solução
Não, objective-C categorias não são uma implementação do visitante padrão.Categorias não têm uma correspondência exata no padrão de design do mundo, uma vez que a técnica de injeção de métodos em classes existentes sem subclasses não é possível na maioria dos idiomas.Eu diria que é mais perto do decorator pattern, mas que padrão é normalmente implementada com a composição, i.é.envolvendo-a com uma instância do objeto que você deseja para "melhorar".
O visitante modelo é útil para encapsular lógica do algoritmo, que pode ser aplicado a uma variedade de objetos, estruturas, etc.Por exemplo, se você deseja criar o HTML de saída para um gráfico de objetos, você pode (A) escreva um htmlString
método em cada objeto e chamá-lo para cada objeto, ou (B) utilizar o visitante padrão e criar um concreto visitante que sabe como produzir uma saída em HTML para cada nó de visitas.
A primeira abordagem é mais genérico, e a lógica para a tarefa T é dispersa em pequenos pedaços em classes X, Y e Z.A segunda abordagem coloca todos os códigos relacionados em um único visitante objeto, o que tende a simplificar a manutenção e evitar que o "eu esqueci que uma classe..." problema.No entanto, o visitante padrão é, sem dúvida, um pouco pesada para situações simples — onde vale realmente a pena é quando você tem várias paralelo funcionalidades e desejo para abstrair a lógica das classes em que a funcionalidade está sendo executada.Por exemplo, você pode implementar outros visitantes que produzem PDF ou RTF saída, etc.Cada visitante pode cuidar de recursão e chamando a sua própria visita métodos na ordem necessária, e visitantes em separado pode utilizar um completamente distinta ordem.
Deve ser observado que, em muitos idiomas, o visitante padrão utiliza o método sobrecarga (de mesmo nome, assinatura diferente/argumentos).Desde o objective-C não permitir sobrecarga de método, você deve usar diferentes nomes de método, mas isso pode realmente ajudar a evitar erros causados por não saber que a sobrecarga está sendo chamado.
Outras dicas
As categorias podem ser usadas para implementar o padrão do visitante.
@protocol Visit
- (void)acceptVisitor:(MyVisitor *)visitor;
@end
@interface Foo (Visit) <Visit>
@end
@interface Bar (Visit) <Visit>
@end
@implementation MyVisitor
- (void)visit:(id)someObject {
if ([someObject conformsToProtocol:@protocol(Visit)]) {
[(id<Visit>)someObject acceptVisitor:self];
}
}
- (void)visitFoo:(Foo *)foo { ... }
- (void)visitBar:(Bar *)bar { ... }
@end
@implementation Foo (Visit)
- (void)acceptVisitor:(MyVisitor *)visitor {
[visitor visitFoo:self];
}
@end
@implementation Bar (Visit)
- (void)acceptVisitor:(MyVisitor *)visitor {
[visitor visitBar:Self];
}
@end
Isso é mais necessário do que o design clássico de visitantes do GOF, pois não há poluição das interfaces públicas das classes visitadas e tudo pode ser encapsulado na unidade de compilação da classe de visitantes.