Quando eu divido métodos grandes (ou procedimentos ou funções - essa pergunta não é específica para OOP, mas como eu trabalho em idiomas OOP 99% das vezes, é com a terminologia com a qual me sinto mais confortável) em muitos pequenos , Muitas vezes me sinto descontente com os resultados. Torna-se mais difícil argumentar sobre esses métodos pequenos do que quando eram apenas blocos de código no grande, porque quando os extraio, perco muitas suposições subjacentes que vêm do contexto do chamador.
Mais tarde, quando olho para esse código e vejo métodos individuais, não sei imediatamente de onde eles são chamados e penso neles como métodos particulares comuns que podem ser chamados de qualquer lugar do arquivo. Por exemplo, imagine um método de inicialização (construtor ou não) dividido em uma série de pequenos: no contexto do próprio método, você sabe claramente que o estado do objeto ainda é inválido, mas em um método privado comum você provavelmente parte da suposição de que o objeto já foi inicializado e está em um estado válido.
A única solução que vi para isso é a where
cláusula em Haskell, que permite definir pequenas funções que são usadas apenas na função "pai". Basicamente, fica assim:
len x y = sqrt $ (sq x) + (sq y)
where sq a = a * a
Mas outros idiomas que eu uso não têm nada parecido com isso - o mais próximo é definir um lambda em um escopo local, o que provavelmente é ainda mais confuso.
Então, minha pergunta é - você encontra isso e vê que isso é um problema? Se o fizer, como você normalmente o soluciona, principalmente em linguagens OOP "mainstream", como Java / C # / C ++?
Edite sobre duplicatas: como outros observaram, já existem perguntas sobre métodos de divisão e pequenas perguntas que são de uma linha. Eu os li e eles não discutem a questão das suposições subjacentes que podem ser derivadas do contexto do chamador (no exemplo acima, o objeto sendo inicializado). Esse é o ponto da minha pergunta, e é por isso que minha pergunta é diferente.
Atualização: se você seguiu esta pergunta e discussão abaixo, poderá apreciar este artigo de John Carmack sobre o assunto , em particular:
Além da conscientização do código real sendo executado, as funções embutidas também têm o benefício de não possibilitar a chamada da função de outros lugares. Isso parece ridículo, mas há um ponto nisso. À medida que a base de código cresce ao longo dos anos de uso, haverá muitas oportunidades para usar um atalho e chamar uma função que faz apenas o trabalho que você acha que precisa ser feito. Pode haver uma função FullUpdate () que chama PartialUpdateA () e PartialUpdateB (), mas em alguns casos particulares você pode perceber (ou pensar) que você só precisa fazer PartialUpdateB () e está sendo eficiente evitando a outra. trabalhos. Muitos e muitos erros resultam disso. A maioria dos erros é resultado do estado de execução não ser exatamente o que você pensa que é.