Existe um antipadrão para descrever esse método de codificação? [fechadas]


26

Eu tenho uma base de código em que o programador costumava encerrar as coisas em áreas que não fazem sentido. Por exemplo, dado um registro de erros, você pode fazer logon via

ErrorLog.Log(ex, "friendly message");

Ele acrescentou vários outros meios para realizar exatamente a mesma tarefa. POR EXEMPLO

SomeClass.Log(ex, "friendly message");

O que simplesmente se vira e chama o primeiro método. Isso adiciona níveis de complexidade sem nenhum benefício adicional. Existe um anti-padrão para descrever isso?


36
"Bad codificação" cobre;)
Oded

12
Depende. É um invólucro para uma biblioteca de log? Se já houve a chance que poderia ser trocado isso realmente é uma boa prática ...
Rig

3
@ortabac: O problema com o "código baklava" é que ele realmente soa bem e saboroso e, portanto, desejável.
FrustratedWithFormsDesigner

10
O que esse programador diz quando você os adiciona, por que eles estão adicionando esses métodos? A compreensão de seu raciocínio deve facilitar a educação deles.
Keith

3
Parece um nível de indireção , o que pode ser bom quando você deseja evitar o acoplamento entre duas classes, como o @Rig apontou. Talvez tenha sido apenas um programador que sofre de patternitis - simplesmente tentando algum padrão para resolver um problema que não existe, violando o KISS.
Fuhrmanator 14/11/12

Respostas:


54

Só vale a pena chamar algum hábito ruim de codificação de Antipadrão, se for razoavelmente disseminado.

O resto chamamos de "código de lixo" ...


Se eu sugerisse um nome para esse mau hábito em particular, seria "Transtorno Obsessivo de Abstração" :-)


9
Eu sempre usei "Indirection Hell".
21412 Dan Neely

27

Não, não é um anti-padrão, mas eu levantaria os seguintes problemas.

Violação do princípio de responsabilidade única

O SRP diz que uma classe deve ter um motivo para mudar. Adicionar um método de logger significa que a classe também precisará ser alterada se a lógica de log for alterada.

Violação de um is-arelacionamento

As classes base não são caixas de ferramentas nas quais você pode adicionar vários métodos de conveniência.

Fazer isso de maneira eficaz combina todas as classes herdadas às implementações que a classe base possui.

Compare isso com a composição.


1
"Problema de responsabilidade única"? SRP? Talvez você pretendesse escrever o Princípio da Responsabilidade Única? Apenas conectando os dois aqui. :)
zxcdw

8

Não que isso o torne aceitável, mas isso poderia ser apenas uma refatoração inacabada. Talvez o SomeClass.log () tenha sua própria lógica e tenha sido implementado primeiro. E depois eles perceberam que deveriam estar usando ErrorLog.Log (). Então, em vez de alterar 100 lugares onde SomeClass.Log () é chamado, eles apenas delegaram para o ErrorLog.Log (). Pessoalmente, eu mudaria todas as referências a ErrorLog.Log () ou, pelo menos, comente SomeClass.log () para dizer por que ele delega da maneira que faz.

Apenas algo a considerar.



4

Não tenho certeza de descrever isso como uma ofensa ao princípio de responsabilidade única, porque se houver uma alteração na assinatura do método ErrorLog (o método chamado por SomeClass), todo código de cliente que chamar esse método falhará.

Obviamente, há uma maneira de usar herança (ou criar classes que precisam de log implementando uma interface de log) lá.


Ainda é uma prática ruim porque: 1) é improvável que seja alterada 2) se for alterada, eles podem apenas criar uma classe de wrapper com o mesmo nome e alterar as importações.
kevin Cline

2
+1. E aqui está o "tio Bob" (Robert Martin) argumentando em favor da centralização de dependências em um número limitado de módulos, em vez de espalhá-las pelo código.
MarkJ

3

Ou poderíamos ver isso como um "momento de aprendizado" :)

Seu desenvolvedor pode estar no meio de uma boa ideia. Suponha que você queira ter o requisito de que todos os seus objetos de negócios sejam capazes de log inteligente. Você pode definir:

   public interface IBusinessObjectLogger
   {
       void Log(Exception ex, string logMessage)
   }

Agora interno aos seus objetos, você pode usar o objeto ErrorLog para fazer o log, enquanto o código SomeClass adiciona valor específico ao objeto na mensagem de log. Você pode estender ainda mais suas APIs de log para implementar a funcionalidade de log com base em arquivo, db ou com base em mensagens sem tocar em objetos de negócios.


3

Não tenho certeza se isso é automaticamente mau.

Se você está chamando SomeClass.Log, certamente é ruim, mas se o Log estiver sendo usado apenas no WITHIN SomeClass, está cortando o acoplamento e eu chamaria isso de aceitável.


2

Na verdade, isso é bastante comum em certos estilos de codificação, e o básico da linha de pensamento não é, por si só, um antipadrão.

Provavelmente, é o resultado de alguém codificando por necessidade, sem conhecimento da base de código mais ampla: "OK, esse código precisa registrar um erro, mas essa função não é o objetivo principal do código. Portanto, preciso de um método / classe que faça isso para mim". Essa é uma boa maneira de pensar; mas, sem saber que o ErrorLog existia, eles criaram SomeClass. Eles então encontraram o ErrorLog em algum momento posterior e, em vez de substituir todos os usos do método que eles colocaram, fizeram o método chamar ErrorLog. É aí que isso se torna um problema.


2

Complexidade acidental é a complexidade que surge em programas de computador ou em seu processo de desenvolvimento que não é essencial para o problema a ser resolvido. Embora a complexidade essencial seja inerente e inevitável, a complexidade acidental é causada pela abordagem escolhida para resolver o problema.

http://en.wikipedia.org/wiki/Accidental_complexity


1

Pode ser um abuso / mal-entendido do Padrão de Fachada . Vi coisas semelhantes em uma base de código com a qual trabalhei. Os desenvolvedores passaram por uma fase em que eram loucos por padrões de design sem entender os princípios gerais do design de OO.

Um uso incorreto do padrão Fachada resulta em um borrão dos níveis de abstração nas camadas do aplicativo.


1

O que esse programador está fazendo é agrupar algum código, para que ele não tenha uma dependência direta do módulo de log. Sem informações mais específicas, não é possível fornecer um padrão mais específico. (Que esses invólucros não são úteis é a sua opinião que é impossível concordar ou discordar sem muito mais informações.)

Os padrões nos quais isso pode se encaixar são Proxy , Delegado , Decorador , Composto ou outros que tenham a ver com agrupar, ocultar ou distribuir chamadas. Pode ser uma dessas coisas em um estado incompleto de desenvolvimento.


0

Eu poderia imaginar que seja uma diferença cultural. Talvez haja um bom motivo para ter funcionalidade duplicada nessa base de código específica. Eu poderia imaginar a facilidade de escrever por esse motivo. O programador Python em mim ainda diria que é ruim, já que " Deve haver um-- e de preferência apenas uma maneira --obvious para fazê-lo. ", Mas alguns caras Perl pode estar acostumado ao fato de que " Há mais de um maneira de fazer isso ".


1
A facilidade de escrita inicial não é um bom motivo para duplicação. Pode ser mais fácil escrever código incorreto da primeira vez, mas isso não facilita a escrita de código a longo prazo. O que o novo cara faz com a funcionalidade duplicada? Qual método ele chama? Ele perde tempo procurando-os e lendo-os, apenas para descobrir que eles fazem a mesma coisa.
Kazark

Talvez esse código tenha sido originalmente concebido como um protótipo que, em seguida, foi (ab) usado como um incremento. Nesse caso, a otimização para a escrita inicial teria sido válida, eu acho.
Bengt
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.