Boas Praticas(Construtor)

Pessoal,
trabalho atualmente em um empresa na qual desempenho a função de desenvolvedor, e me deparei com um problema no qual meus conhecimentos me impedem de fazer qualquer comentario!, foi adminitdo que neste projeto em que estou no momento devo usar Classes com construtores do seguinte modo:

 Ou o construtor da minha classe recebe todos os atributos.
 Ou não recebe nada.

não posso mesmo usar construtores parciais? O motivo citado foi que isso fere as boas praticas de programação.

Grato pela atenção de todos!!!

Entao do ponto de vista do seu pessoal isso é errado?

public Room(String number, double price) {
     this(number, price, false);
}

public Room(String number, double price, boolean isSmoking) {
     this.number = number;
     this.price = price;
     this.smoking = isSmoking;
}

Pra mim, o que nao tem sentido em alguns casos é um construtor vazio.

penso que construtores parciais sao para classes onde se
pode trabalhar com seus objetos sem todas as informacoes completas, ou seja,
do modo default funciona, ou voce pode personalizar.

no caso de classes de modelo, de negocio, eh dificil nao se usar todos os
atributos. nao sao manipuladas partes, mas o todo

     Pois é pessoal,  do ponto do vista do pessoal aqui o exemplo dado pelo fabiocsi esta errado! segundo me disseram, o motivo é que isso não atende as boas praticas de programação. Como não estou certo disso, resolvi perguntar se alguem já se deparou com algo semelhante. No meu caso essas classes as quais cito aqui, são classes utilizadas para reunir atributos de entrada/saida dos meus componentes, ou como o exemplo abaixo.
Query query = EntityManager.createQuery("select new MeuConstrutor(o.nome, o.endereco, o.telefone) from Cliente_Table");
    No caso real eu recebo elementos de tabelas distintas e por isso uso o construtor parcial, sei que existe outra maneira de fazer isso, mas o que eu fiz esta errado mesmo? vai contra as boas praticas de programação?

Valeu!!!

[quote=Canhoto]Pessoal,
trabalho atualmente em um empresa na qual desempenho a função de desenvolvedor, e me deparei com um problema no qual meus conhecimentos me impedem de fazer qualquer comentario!, foi adminitdo que neste projeto em que estou no momento devo usar Classes com construtores do seguinte modo:

 Ou o construtor da minha classe recebe todos os atributos.
 Ou não recebe nada.

não posso mesmo usar construtores parciais? O motivo citado foi que isso fere as boas praticas de programação.

[/quote]

Ter vários construtores é potencialmente perigoso se vc não souber o que está fazendo. Seguindo essas regras acima ha garantias que mesmo que o programador não saiba o que está fazendo, a coisa funciona.

O construtor deve inicilizar o estado do objeto. O estado do objeto tem que ser consistente a todo o momento.
Se o construtor é sem parametros, significa que o estado inicial do objeto é padrão e determinado pelo proprio construtor.

Se o construtor tem todos os parametros , o estado do objeto é únicamente determinado pelo valor desses parametros. O problema aqui é que não devem passar todos os dados do estado do objeto no construtor. apenas aqueles , sem os quais o estado seria inconsistente.
Se existem muitos parametros deve ser usado o padrão Builder ou Prototype.

Por exemplo:


class Displayer {

    public void display(String s);
}

class Writer {

   private Display display;
   private String message = "";

   public Writer(){} // ERRADO

   public Writer(Display display){ // OK
    this.display = display;
   } 

   public  void write (){
       display.display(message);
  }

   public void setMessage(String message){ 
  this.message=message;
  }
}

A classe write depende do display. Se ele não for passado no construtor vai dar erro em write(). Então, obrigatoriamente o construtor tem que ter esse parametro. Contudo, o writer pode funcionar corretamente
sem que “message” seja passada como parametro no construtor.

Cada atributo é um caso. Usar tudo ou nada é limitativo, mas impõe mais controle para programadores inexperientes. Contudo, do ponto de vista puro de design é errado.

Pra ser sincero, nunca vi isso na minha vida… haha

Para que existe sobrecarga de construtor então?!

A Sun criou a sobrecarga de construtor para os programadores usufruir desse recurso de acordo com sua necessidade!

Você não leu o título do post - “Boas práticas”.
“Boas práticas” é aquela lista de coisas que você tem de fazer porque se você fizer tudo que é possível pode ter problemas depois (nem que seja com seu chefe).

use construtor para receber dependencias! assim ninguem te cria num estado incosistente!

Poderia dar um exemplo, não entendi mto bem.

[quote=thingol][quote]
Pra ser sincero, nunca vi isso na minha vida… haha

Para que existe sobrecarga de construtor então?!

A Sun criou a sobrecarga de construtor para os programadores usufruir desse recurso de acordo com sua necessidade!
[/quote]

Você não leu o título do post - “Boas práticas”.
“Boas práticas” é aquela lista de coisas que você tem de fazer porque se você fizer tudo que é possível pode ter problemas depois (nem que seja com seu chefe).
[/quote]

Voltando às boas práticas quanto aos construtores de classe, qual sua opnião?

Digamos que você tenha um objeto Cliente que represente um registro do banco de dados, e nenhuma das colunas possa ser NULL. Exemplo:

class Cliente {
    int codigo;
    String nome;
    String endereco;
    public Cliente (int c, String n, String e) {
        codigo = c; nome = n; endereco = e;
    }
}

Se você tiver um construtor que não inicialize todos os campos, só alguns deles, isso quer dizer que os outros campos vão ficar com valor indefinido (null).
Digamos que você precise depois desse objeto para inserir no banco de dados. Aí você vai ter um problema, porque ou você tem de ficar checando todos os dados antes de pôr o tal objeto como registro no banco, ou então vai receber um erro na inserção.

Entendi.

Pelo que pude ver aqui, reunindo todas as informações, o(s) construtor(es) tem que manter a consistência da classe para uso posterior. Seja para persistência no banco ou utilização no negócio.

É isso?

[quote=thingol]Digamos que você tenha um objeto Cliente que represente um registro do banco de dados, e nenhuma das colunas possa ser NULL. Exemplo:

class Cliente {
    int codigo;
    String nome;
    String endereco;
    public Cliente (int c, String n, String e) {
        codigo = c; nome = n; endereco = e;
    }
}

Se você tiver um construtor que não inicialize todos os campos, só alguns deles, isso quer dizer que os outros campos vão ficar com valor indefinido (null).
Digamos que você precise depois desse objeto para inserir no banco de dados. Aí você vai ter um problema, porque ou você tem de ficar checando todos os dados antes de pôr o tal objeto como registro no banco, ou então vai receber um erro na inserção.
[/quote]

Mas isso é o mínimo que se espera do kra meu!!! Você poderia nos dar uma boa explicação do POR QUÊ várias sobrecargas de um construtor fere as boas práticas…!

Se a dúvida é só essa então a resposta é: Sobrecarregar o construtor não fere boas práticas.

Boas Práticas de construtor:

) Não deve lançar exceções além de IllegalArgumentException
) Não deve produzir objetos com estado inconsistente.
) Não deve invocar métodos do objeto que possam ser sobre-escritos (não final).
) Não deve ser sincronizado
) Deve ser explicitamente definido mesmo quando não ha nada a fazer (ou: não use o constutor padrão)
) Não deve inicializar campos para valores padrão.

Além disso eu acho que não deve aceitar todos os campos que representam seu estado quando eles são muitos. Deve ser usando o padrão Builder ou Factory Method

Eu acho que essa história de “Boas práticas” é um substituto grosseiro e preguiçoso para o correto entendimento e compreensão dos problemas.

(Eu costumo sempre dizer que até o “goto” é válido, desde que você saiba o que está fazendo. É o dito “zen da programação”).

Você não pode ter várias sobrecargas para um construtor só porque o programador preguiçoso vai fazer m***?

Em vez disso, seria interessante ensinar cada programador por que é que ele não deve abusar de certas coisas.

[quote=thingol]Eu acho que essa história de “Boas práticas” é um substituto grosseiro e preguiçoso para o correto entendimento e compreensão dos problemas.

(Eu costumo sempre dizer que até o “goto” é válido, desde que você saiba o que está fazendo. É o dito “zen da programação”).

Você não pode ter várias sobrecargas para um construtor só porque o programador preguiçoso vai fazer m***?

Em vez disso, seria interessante ensinar cada programador por que é que ele não deve abusar de certas coisas. [/quote]

Não entendi exactamente qual é a tua posição. O goto não é válido. Se fosse ainda seria usado. Programação estruturada não pode conter uma instrução não-estruturada. Isso é que dá m@#@#. Por isso o goto é reservado em Java. Não é para usar. Java tem labels que é uma especie de goto sem usar goto. É estruturado.

Seria interessante ensinar se o programador qer aprender. Se ele aprender as regras básicas ele consegue chegar nas boas práticas. São apenas corolários dessas regras. É só dar à manivela.
A lista de boas práticas é para ser lida pelo programador novato ou perguiçoso ( ou ambos) para não fazer m#$%#$% em programas sérios. E pode ser seguida por qualquer fazer as coisas bem à primeira.

Claro, existem exceções às boas práticas exactamente por elas serem corolários das regras principais e portanto não cobrem todas as hipoteses.

Eu ficaria contente se o programador soubesse que existem listas de boas práticas. Mais do que se ele soubesse que existem padrões de projeto.

Qaundo eu preciso criar objetos dos quais pode haver confusão na hora de outra pessoa construi-lo COMO BOA PRÁTICA eu abstraio a construção do objeto para os outros desenvolvedores. Exemplo:

public class Cliente{

Integer id;
String nome;
String idade;
Double contaBancaria;

public Cliente(Integer id){
   this.id = id
}

public Cliente(Double contaBancaria, Integer id){
   this.id = id;
   this.contaBancaria = contaBancaria;
}
}

Então eu quero consultar o nome do cliente via JPA…Será que eu preciso passar no construtor a ContaBancaria ??? NÃO. Apenas o ID.

Então eu poderia explicar isso aos progamadores sem noção ou criar uma fábrica com métodos auto explicativos:


public getCliente {

public Cliente novoClienteComID(Integer id){
return new Cliente(id);
}

public Cliente novoClienteComContaBancaria(Double conta, Integer id){
return new Cliente(conta,id);
}
}

A idéia que eu quis passar talvez não se resuma ao código apresentado, então o que eu quis tratar é que DIZER QUE NÃO EXSITEM CONSTRUTORES VAZIOS É FALTA DE EXPERIÊNCIA EM JAVA.

Construtor como muitos disseram serve para garantir o estado do objeto.

Ainda bem que vc optou pela segunda. Porque a primeira não funciona. Vc não pode explicar a mesma coisa a todos os usuários da classe. (imagine um projeto opensource)

Isso que vc usou é a aplicação do factory method mas para seria melhor assim


class Cliente{

public static Cliente cliente(Integer id){
// valida parametros null não são aceitos
Cliente c = new Cliente();
c.id = id;

return c;
}

public static Cliente cliente(Double conta, Integer id){
// valida parametros null não são aceitos
Cliente c = new Cliente();
c.id = id;
c.conta = conta;

return c;
}

 private Cliente(){}
}

Agora sim. Não tem como criar clientes não usem um desses métodos.

O código foi só de exemplo então não era pra se basear nesses detalhes…como eu disse a idéia era passar os conceitos mesmo.

editado: erro de leitura meu.

ahm!?