Devo carregar os dados do meu objeto Java em construção, ou explicitamente através de uma chamada de método?

StackOverflow https://stackoverflow.com/questions/2419393

  •  19-09-2019
  •  | 
  •  

Pergunta

Esta é uma questão de design. Eu estou tentando decidir entre 2 implementações.

A fim de explicar adequadamente esse eu precisar de um exemplo. Assim, por uma questão de exemplo:

Eu tenho uma classe que gera um relatório sobre, digamos, certos valores do mercado de ações em um dia específico. Eu criar um objeto StockMarketReportGenerator, passando a data de hoje, e gera um relatório com base em valores de mercado de hoje.

O StockMarketReportGenerator "tem um" objeto StockMarketData. A finalidade do objeto StockMarketData é conter todos os valores do mercado de ações que são armazenadas em uma tabela (provavelmente chamado StockMarket :)) no banco de dados, e alguns outros valores calculados a partir dos dados da tabela. Ele tem métodos privados que se conectam com o banco de dados, recuperar os dados, fazer os cálculos necessários, e armazenar os valores finais em variáveis ??de membro do objeto. (Em seguida, ele tem métodos getter para expor esses valores, mas há métodos setter.) A classe StockMarketData é basicamente um "titular" para valores de dados do mercado de ações. Eu tenho uma função central chamado algo como "calculateStockMarketData()" que chama todos esses métodos auxiliares privadas e configura o objeto. (Estou ciente de que toda esta transformação poderia realmente ser mais facilmente manipulados por um quadro como o Hibernate;. Mas a decisão foi tomada para fazê-lo manualmente, pois é um projeto muito pequeno, um pouco temporária e não vale o setup)

A minha pergunta é esta - de minha classe ReportGenerator, eu só preciso do objeto StockMarketData para acessar suas propriedades / variáveis ??de membro - pós-processamento e pós-cálculos. O que significa que realmente, eu quero pegar o objeto pré-cheia com dados. E assim que eu mantenho o método calculateStockMarketData privado e chamá-lo automaticamente a partir do StockMarketData construtor. Mas eu estou me sentindo um pouco desconfortável em fazer toda a minha transformação em um construtor e depois não ter quaisquer métodos públicos. É este uma falha de projeto? Ou é realmente a forma mais lógica para fazer isso? Basicamente, qual dos 2 implementações seguintes é melhor?

1) (Minha implementação atual) Faça o método calculateStockMarketData() privado central e chamá-lo a partir do construtor método StockMarketData (passando a data de hoje), para que sempre que você tem um objeto StockMarketData, já está cheio. Então tudo que eu precisaria da classe ReportGenerator antes de eu começar a usar as propriedades do objeto é a linha:

StockMarketData myData = new StockMarketData(someDate);

2) Faça o público método calculateStockMarketData() central, de modo que, a fim de criar um objeto StockMarketData você precisa chamar explicitamente o método. Então, a partir da classe ReportGenerator eu código:

StockMarketData myData = new StockMarketData(someDate);
myData.calculateStockMarketData();

As primeiras me parece o melhor design, especialmente porque há então nenhuma possibilidade de utilizar as propriedades do objeto antes que eles são inicializados. Mas também estou inseguro sobre as normas relacionadas com a execução de uma grande quantidade de código a partir de um construtor ... Qual eu devo escolher?

Foi útil?

Solução

Eu iria com o número 2, especialmente se houver uma possibilidade de adicionar métodos para a classe que não dependem de que os dados de estar lá.

Por outro lado, se você considerar a classe para estar em um estado inválido sem os dados preenchido, você deve fazê-lo na construção.

Outras dicas

Martin Fowler tem escrito um bom ensaio sobre injeção de dependência (Construtor vs. Setter injeção) . Seu conselho é "tanto quanto possível, para criar objetos válidos no tempo de construção".

IMO, é melhor para a construção de objetos válidos se possível, porque torna mais fácil de ler / observar o comportamento do código, desde que você pode assumir que os objetos foram construídos corretamente, e você tem menos bugs relacionados a objetos não sendo preenchido corretamente. A questão do setter vs. construtor injeção é diferente do que você está perguntando sobre porém, que é uma questão de onde para executar a sua lógica de negócios. Eu acho que é melhor usar o construtor para criar um objeto válido e, em seguida, executar a lógica de negócio real em outro método público (o seu nº 2), de modo que a construção do objeto pode acontecer em um horário diferente do que a lógica de negócio real.

Eu sempre carregar explicitamente, pós-construção.

Chamar um banco de dados a partir de um construtor pode fazer para difícil depuração, código mais frágil, inflexível, e causar problemas de desempenho se o uso do objeto de alterações.

Uma boa prática é a de não executar um monte de código dentro de um construtor.

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