Pergunta

Que fatores determinam qual abordagem é mais apropriada?

Foi útil?

Solução

Acho que ambos têm seus lugares.

Você não deve simplesmente usar DoSomethingToThing(Thing n) só porque você pensa que "a programação funcional é boa".Da mesma forma, você não deve simplesmente usar Thing.DoSomething() porque "a programação orientada a objetos é boa".

Acho que tudo se resume ao que você está tentando transmitir.Pare de pensar no seu código como uma série de instruções e comece a pensar nele como um parágrafo ou frase de uma história.Pense em quais partes são mais importantes do ponto de vista da tarefa em questão.

Por exemplo, se a parte da 'frase' que você gostaria de enfatizar for o objeto, você deverá usar o estilo OO.

Exemplo:

fileHandle.close();

Na maioria das vezes, quando você passa identificadores de arquivo, a principal coisa em que você pensa é em manter o controle do arquivo que ele representa.

Contraexemplo:

string x = "Hello World";
submitHttpRequest( x );

Neste caso, enviar a solicitação HTTP é muito mais importante do que a string que é o corpo, então submitHttpRequst(x) é preferível x.submitViaHttp()

Escusado será dizer que estes não são mutuamente exclusivos.Você provavelmente terá realmente

networkConnection.submitHttpRequest(x)

em que você mistura os dois.O importante é você pensar quais partes serão enfatizadas e o que você estará transmitindo ao futuro leitor do código.

Outras dicas

Para ser orientado a objetos, diga, não pergunte: http://www.pragmaticprogrammer.com/articles/tell-dont-ask.

Então, Thing.DoSomething() em vez de DoSomethingToThing(Thing n).

Se você estiver lidando com o estado interno de uma coisa, Thing.DoSomething() faz mais sentido, porque mesmo se você alterar a representação interna de Thing, ou como ela funciona, o código que fala com ela não precisa mudar.Se você estiver lidando com uma coleção de coisas ou escrevendo alguns métodos utilitários, o estilo processual DoSomethingToThing() pode fazer mais sentido ou ser mais direto;mas ainda assim, geralmente pode ser representado como um método no objeto que representa essa coleção:por exemplo

GetTotalPriceofThings();

contra

Cart.getTotal();

Realmente depende de quão orientado a objetos é o seu código.

  1. Coisa.DoAlguma coisa é apropriado se Coisa for o sujeito da sua frase.
    • DoSomethingToThing(Coisa n) é apropriado se Coisa for o objeto de sua frase.
    • ThingA.DoSomethingToThingB(ThingB m) é uma combinação inevitável, já que em todas as linguagens que consigo imaginar, as funções pertencem a uma classe e não são de propriedade mútua.Mas isso faz sentido porque você pode ter um sujeito e um objeto.

A voz ativa é mais direta do que a voz passiva, portanto, certifique-se de que sua frase tenha um assunto que não seja apenas “o computador”.Isso significa usar o formulário 1 e o formulário 3 com frequência e o formulário 2 raramente.

Para maior clareza:

// Form 1:  "File handle, close."
fileHandle.close(); 

// Form 2:  "(Computer,) close the file handle."
close(fileHandle);

// Form 3:  "File handle, write the contents of another file handle."
fileHandle.writeContentsOf(anotherFileHandle);

Concordo com Orion, mas vou reformular o processo de decisão.

Você tem um substantivo e um verbo/um objeto e uma ação.

  • Se muitos objetos deste tipo utilizarem esta ação, tente tornar a ação parte do objeto.
  • Caso contrário, tente agrupar a ação separadamente, mas com ações relacionadas.

Gosto dos exemplos de arquivo/string.Existem muitas operações de string, como "SendAsHTTPReply", que não acontecem para uma string média, mas acontecem frequentemente em uma determinada configuração.No entanto, você basicamente sempre fechará um arquivo (espero), então faz todo o sentido colocar a ação Close na interface da classe.

Outra maneira de pensar nisso é comprar parte de um sistema de entretenimento.Faz sentido agrupar um controle remoto de TV com uma TV, porque você sempre os usa juntos.Mas seria estranho agrupar um cabo de alimentação para um videocassete específico com uma TV, já que muitos clientes nunca usarão isso.A ideia chave é com que frequência esta ação será usada neste objeto?

Não há informações suficientes aqui.Depende se o seu idioma suporta a construção "Thing.something" ou equivalente (ou seja,é uma linguagem OO).Nesse caso, é muito mais apropriado porque esse é o paradigma OO (os membros devem estar associados ao objeto em que atuam).Em um estilo processual, é claro, DoSomethingtoThing() é sua única opção...ou ThingDoSomething()

DoSomethingToThing(Thing n) seria mais uma abordagem funcional, enquanto Thing.DoSomething() seria mais uma abordagem orientada a objetos.

Essa é a escolha de Programação Orientada a Objetos versus Programação Processual :)

Acho que as vantagens OO bem documentadas se aplicam ao Thing.DoSomething()

Aqui estão alguns fatores a serem considerados:

  • Você pode modificar ou estender o Thing aula.Se não, use o primeiro
  • Pode Thing ser instanciado.Caso contrário, use o último como método estático
  • Se Thing realmente ser modificado (ou seja,tem propriedades que mudam), prefira o último.Se Thing não for modificado, o último é igualmente aceitável.
  • Caso contrário, como os objetos devem ser mapeados em objetos do mundo real, escolha o método que parece mais fundamentado na realidade.

Mesmo que você não esteja trabalhando em uma linguagem OO, onde você teria Thing.DoSomething(), para a legibilidade geral do seu código, tendo um conjunto de funções como:

ThingDosomething () ThingDoanOtherTask () ThingWedosomethingElse ()

então

OutraCoisaDoAlguma()

e assim por diante é muito melhor.

Todo o código que funciona em "Thing" está em um único local.É claro que "DoSomething" e outras tarefas devem ser nomeadas de forma consistente - então você tem um ThingOneRead(), um ThingTwoRead()...agora você deve entender.Quando você voltar a trabalhar no código daqui a doze meses, apreciará dedicar um tempo para tornar as coisas lógicas.

Em geral, se “algo” é uma ação que “coisa” naturalmente sabe fazer, então você deve usar thing.doSomething().Isso é um bom encapsulamento OO, porque caso contrário DoSomethingToThing(thing) teria que acessar possíveis informações internas de "thing".

Por exemplo fatura.getTotal()

Se “algo” não faz naturalmente parte do modelo de domínio de “coisa”, então uma opção é usar um método auxiliar.

Por exemplo:Logger.log(fatura)

Se é provável que DoingSomething para um objeto produza um resultado diferente em outro cenário, sugiro oneThing.DoSomethingToThing (anotherThing).

Por exemplo, você pode ter duas maneiras de salvar algo em seu programa, então você pode adotar um DatabaseObject.Save(thing) SessionObject.Save(thing) seria mais vantajoso do que thing.Save() ou thing.SaveToDatabase ou thing.SaveToSession() .

Raramente passo parâmetros para uma classe, a menos que esteja recuperando propriedades públicas.

Para complementar a resposta de Aeon, depende da coisa e do que você deseja fazer com ela.Portanto, se você está escrevendo Thing e DoSomething altera o estado interno do Thing, a melhor abordagem é Thing.DoSomething.No entanto, se a ação faz mais do que alterar o estado interno, então DoSomething(Thing) faz mais sentido.Por exemplo:

Collection.Add(Thing)

é melhor que

Thing.AddSelfToCollection(Collection)

E se você não escreveu Thing e não pode criar uma classe derivada, então você não tem escolha a não ser fazer DoSomething(Thing)

Mesmo na programação orientada a objetos, pode ser útil usar uma chamada de função em vez de um método (ou, nesse caso, chamar um método de um objeto diferente daquele em que o chamamos).Imagine uma estrutura simples de persistência de banco de dados onde você gostaria apenas de chamar save() em um objeto.Em vez de incluir uma instrução SQL em cada classe que você gostaria de salvar, complicando assim o código, espalhando o SQL por todo o código e tornando a alteração do mecanismo de armazenamento uma PITA, você poderia criar uma interface definindo save(Class1), save(Class2 ) etce sua implementação.Então você estaria chamando databaseSaver.save(class1) e teria tudo em um só lugar.

eu tenho que concordar com Kevin Conner

Tenha também em mente o chamador de qualquer um dos dois formulários.O chamador é provavelmente um método de algum outro objeto que definitivamente faz algo com o seu Thing :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top