Como faço funcionar no PADRÃO FACTORY

E ae Pessoal.

Amigos estou num impasse não consegui entender como faço estas classes de forma abstrat utilizando o padrão Factory.Estou no segundo semestre do técnico e estudando Java
Pois primieiro devo aplicar o padrão factory e depois vou aplicar Testes com Junit.
Algué pode me ajudar a montar isso?
Já vi vários vídeos no youtube mas não consegui passar deste ponto que estou
É uma classe NotaFiscal que deve receber os dados da quantidade da classe Itens multiplicado pelo valor do produto xxx da classe Produto.

Classe NotaFiscal

public abstract class NotaFiscal {
	
	private int codigo;
	private String data;
	private String uf;
	
	public  NotaFiscal(int codigo, Date data, String uf) {
		this.codigo = codigo;
		this.data = this.data;
		this.uf = uf;
	}
	public abstract void calcular();

	public void adicionarItem( ) {  }
                }

Classe ItemNota

public class ItemNota extends NotaFiscal{
	private int quant;

	
	public ItemNota(int codigo,Date data, String uf)
	{
			super(codigo,data,uf);
			this.quant = quant;
	}
	
	public void adicionarItem( ) {
		super.adicionarItem();
		System.out.println("vamos ver item"+quant);
	}
	//metodo get de retorno
	public int getQuant() {
		return quant;
	}
	public void setQuant(int quant) {
		this.quant = quant;
	}

	@Override
	public void calcular() {
		// TODO Auto-generated method stub
	}
}

E finalmente a classe Produto

public abstract class Produto extends ItemNota{

	public Produto(int codigo, Date data, String uf) {
		super(codigo, data, uf);
		// TODO Auto-generated constructor stub
	}

	private int codigo;
	private String descricao;
	private float preco; 
		
	   public int getcodigo() {
	         return codigo;
	     }
	     
	     public String getdescricao() {
	         return descricao;
	     }
	     public float getpreco() {
	        return preco;
	     }
	     
	     public void setcodigo(int codigo) {
	         this.codigo = codigo;
	         this.descricao = descricao;
	         this.preco = preco;
	         
	     }    

E ai beleza?

Pra se criar um padrão factory, seria mais interessante utilizar classes concretas e interfaces ao invés de classes abstratas.
Em Java, é sempre bom programar orientado a interfaces, pois assim você pode implementar quantas achar necessário.
Já usando classes abstratas, além de você “bloquear” instâncias de seus objetos, você não pode estender seus filhos a mais ninguém.

O melhor pra se usar classes abstratas é se a classe não tem sentido em ser instanciada, no seu caso, NotaFiscal e Produto podem ou devem ser instanciados?
Se sim, não faz sentido utilizar abstract.

Vou mudar um pouco a lógica pra tentar te mostrar o padrão factory implementado.
Vamos criar uma fábrica de pessoas ok? E pra isso criarei minha classe Pessoa (essa sim deve ser abstrata pois nunca será instanciada):

public abstract class Pessoa {
   public String getNome() {...}
   public void setNome() {...}
   public abstract String getTipo(); // importante em classes abstratas 
}

Logo crierei dois tipos de Pessoas (física e jurídica):

public class PessoaFisica extends Pessoa {
   public String getTipo() {
      return "Pessoa Física";
   }
}

public class PessoaJuridica extends Pessoa {
   public String getTipo() {
      return "Pessoa Jurídica";
   }
}

Classes criadas, agora criaremos a “fábrica” pra elas:

public class PessoaFactory {
   public Pessoa createPessoa(String tipo) {
      if (tipo.contains("Física")) {
         return new PessoaFisica();
      }
      if (tipo.contains("Jurídica")) {
         return new PessoaJuridica();
      }
   }
}

E por fim testaremos o tipo que a fábrica criou:

public class TestaFabricaPessoas {
   public static void main(String[] args) {
      PessoaFactory factory = new PessoaFactory();
      System.out.println("Tipo da pessoa fabricada: " + factory.createPessoa("Física").getTipo());      
   }
}

Desculpe o post tão longo, mas acho que esse exemplo pode te ajudar.

Bha acho que entendi tua explicação.

Eu estou em duvida pro que como eu chamo o metodo main pra executar e inserir os dados pra gerar os calculos…mas vou tentar aplicar nos teus exemplos.

Show de bola , muito obrigado…vou tentar !

Abrass

[quote=CristianoRSul]Bha acho que entendi tua explicação.

Eu estou em duvida pro que como eu chamo o metodo main pra executar e inserir os dados pra gerar os calculos…mas vou tentar aplicar nos teus exemplos.

Show de bola , muito obrigado…vou tentar !

Abrass
[/quote]

Dúvida com cálculos no main? Desculpe cara, mas poderia ser mais específico?

Ok.
Estou tentado desenvolver este trabalho onde tenho uma classe NotaFiscal , ItemNota e Produto, e outras q são base de calculo de icms da nota.

A classe Produto tem atributos cod,descricao e preco.
A classe ItemNota tem atributo quant, e metodo getvalorParcial():void
A classe NotaFiscal atibutos codigo,data e uf, metodos : +adicionar item (prod: Produto, qtd: int), +calcularTotal():float, +calcularTotalSemImpostos():float

Com isso tem uma classe CalculoIcmsRS e outra CalculoIcmsSC que quando eu especifico se é RS o valor da nota calculando vezes a quantidade da classe ItemNota do valor do Produto vou ter o ValorParcial da Nota e o valor acrescido de juros dependendo do estado conforme o icms.

É isso…mais ou menos…e temos de aplicar de singleton para o padrao factory

Entendi, apenas comentando, mas sinceramente não vejo necessidade de usar herança para as classes ItemNota e Produto.

Pois pelo que sei nem todo Produto será um ItemNota correto?
Em casos como E-commerce por exemplo, tenho Produtos em meu carrinho, mas nenhum está com a nota “pendurada” entende?

Não sei se suas classes já estavam criadas assim ou você começou a implementar mas é bom observar esses conceitos de é um e tem um para utilizar maneiras mais flexíveis no seu projeto com menor acoplamento.

Se você parar para ver, suas classes estão totalmente amarradas por causa da herança, não seria mais fácil você adicionar uma lista de Produtos em sua NotaFiscal?

E também você poderia criar uma interface CalculoICMS com os métodos que você precisa que todos os estados precisam implementar já que o que muda é a taxa de ICMS:

interface CalculoICMS {
   // metodos que todo estado deve implementar
}

Depois é só criar um atributo CalculoICMS na sua classe NotaFiscal junto com a lista de Produtos:

public class NotaFiscal {
   private CalculoICMS icms; // aqui ele pode aceitar ICMS de qualquer estado, desde que esse "implements" a interface
   private List<Produto> itens;
   ...
}

Dessa forma praticamente o ItemNota irá morrer e seus métodos e atributos podem ser divididos entre Produto (quantidade) e NotaFiscal (getValorParcial).

Desculpe ser tão chato e fugir um pouco do assunto do tópico, mas é bom dar umas dicas para que seu projeto possa crescer sem estar tão amarrado e a gente se empolga, sabe como é, rsrsrs

Bem capaz…
Muito boa a sua visão, mas como estou tentando fazer isso segui os conceitos passados.Pois não entendo muito ainda o conceito de herança e a utilização de Get’s e Setter’s. Quando usar e onde e qual classe irá precisar e coisa e tal.

Vou ver se conseigo aplicar teus apontamentos.

Só valeu, pelas dicas.

Obrigado.

Nesse caso recomendo a apostila gratuita FJ-11 da caelum, esses conceitos são bem demonstrados.

Consegui melhorar o código e parei no entendimento de utilizar listas.Não compreendi como pegar apenas o preco do produto e a quantidade de ItemNota, pois destes devo fazer um cálculo de multiplicação preço x qtd = que vai originar o ValorParcial

ficou assim meu código:

Classe NotaFiscal


package edu;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public abstract class NotaFiscal {

	private int codigo;
	private Date data;
	private String uf;

	private List<ItemNota> items;

	public int getCodigo() {
		return codigo;
	}

	public void setCodigo(int codigo) {
		this.codigo = codigo;
	}

	public Date getData() {
		return data;
	}

	public void setData(Date data) {
		this.data = data;
	}

	public String getUf() {
		return uf;
	}

	public void setUf(String uf) {
		this.uf = uf;
	}

	public List<ItemNota> getItems() {
		return items;
	}

	public void adicionarItem(Produto prod, int qtd) {
		items.add(new Produto(12, 1));

	}

	public float calcularTotal() {
		// return
	}

	public float calcularTotalSemipostos() {
		// return
	}

	public NotaFiscal(Date data, String uf) {
		super();
		this.data = data;
		this.uf = uf;
		this.items = new ArrayList<ItemNota>();
	}

}

Classe ItemNota


public class ItemNota { 
	private Produto produto ;
	private int quant;
	public Produto getProduto() {
		return produto;
	}
	public void setProduto(Produto produto) {
		this.produto = produto;
	}
	public int getQuant() {
		return quant;
	}

	public void setQuant(int quant) {
		this.quant = quant;
	}

	public float getValorParcial () {
		return quant * produto.getPreco();
	}

}
public class Produto {
	private int codigo;
	private String descricao;
	private float preco;

	public Produto(int codigo, String descricao, float preco) {
		super();
		this.codigo = codigo;
		this.descricao = descricao;
		this.preco = preco;
	}

	public int getCodigo() {
		return codigo;
	}

	public void setCodigo(int codigo) {
		this.codigo = codigo;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public float getPreco() {
		return preco;
	}

	public void setPreco(float preco) {
		this.preco = preco;
	}

	@Override
	public String toString() {
		return "Produto [codigo=" + codigo + ", descricao=" + descricao
				+ ", preco=" + preco + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + codigo;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Produto other = (Produto) obj;
		if (codigo != other.codigo)
			return false;
		return true;
	}

}

Conforme as classes acima como faço pra incrmentar os itens de nota na lista no método:

[code] public void adicionarItem(Produto prod, int qtd) {
items.add(new Produto(12, 1));

}[/code]

E aí brother, beleza?

Então, lembra que eu te disse que sua classe ItemNota poderia morrer, pois então, pelo que sua aplicação está crescendo, creio que chegou a hora e vou tentar mostrar o porquê.

A única coisa que sua classe ItemNota faz de diferente é o método getValorParcial que pode ser incluído perfeitamente na classe Produto assim como quantidade:

public class Produto {  
    
    // atributos anteriores ...

    private int quantidade;

    // implementações anteriores ...

    // getter e setter para quantidade aqui ...  

    public float getValorParcial() {
        return this.quantidade * this.preco;
    }
  
    // ...  
  
}

Já na sua classe NotaFiscal, algumas implementações não coincidem, como:

// ...
private List&lt;ItemNota&gt; items; // não será necessário
// ...
public void adicionarItem(Produto prod, int qtd) {  
     items.add(new Produto(12, 1)); // sua lista só aceita ItemNota e não Produto  
}

Nesse método, você precisaria fazer essa implementação para funcionar:

// ...
private List&lt;ItemNota&gt; items;
// ...
public void adicionarItem(Produto prod, int qtd) {
     ItemNota item = new ItemNota();
     item.setProduto(prod);  
     items.add(item);
}

Como você “matou” sua classe ItemNota, poderemos incluir um Produto na lista assim:

// ...
private List&lt;Produto&gt; items; // porque todo Produto implicitamente é um item de nota, mesmo sem herança, devido sua quantidade  e preço parcial
// ...
public void adicionarItem(Produto prod) {  // int qtd não precisa, pois é atributo de produto
     items.add(prod); // mais simples não?
}

A partir daí você pode pegar o valorParcial ou quantidade percorrendo seus itens na sua classe NotaFiscal:

// ...
for (Produto prod : this.items) {
   System.out.println("Produto: " + prod.getDescricao());
   System.out.println("Quantidade: " + prod.getQuantidade());
   System.out.println("Valor parcial: " + prod.getValorParcial());
}
// ...

Por isso frisei que sua classe ItemNota poderia morrer, pescou?

[quote=death]E aí brother, beleza?

Então, lembra que eu te disse que sua classe ItemNota poderia morrer, pois então, pelo que sua aplicação está crescendo, creio que chegou a hora e vou tentar mostrar o porquê.

A única coisa que sua classe ItemNota faz de diferente é o método getValorParcial que pode ser incluído perfeitamente na classe Produto assim como quantidade:

public class Produto {  
    
    // atributos anteriores ...

    private int quantidade;

    // implementações anteriores ...

    // getter e setter para quantidade aqui ...  

    public float getValorParcial() {
        return this.quantidade * this.preco;
    }
  
    // ...  
  
}

Já na sua classe NotaFiscal, algumas implementações não coincidem, como:

// ...
private List&lt;ItemNota&gt; items; // não será necessário
// ...
public void adicionarItem(Produto prod, int qtd) {  
     items.add(new Produto(12, 1)); // sua lista só aceita ItemNota e não Produto  
}

Nesse método, você precisaria fazer essa implementação para funcionar:

// ...
private List&lt;ItemNota&gt; items;
// ...
public void adicionarItem(Produto prod, int qtd) {
     ItemNota item = new ItemNota();
     item.setProduto(prod);  
     items.add(item);
}

Como você “matou” sua classe ItemNota, poderemos incluir um Produto na lista assim:

// ...
private List&lt;Produto&gt; items; // porque todo Produto implicitamente é um item de nota, mesmo sem herança, devido sua quantidade  e preço parcial
// ...
public void adicionarItem(Produto prod) {  // int qtd não precisa, pois é atributo de produto
     items.add(prod); // mais simples não?
}

A partir daí você pode pegar o valorParcial ou quantidade percorrendo seus itens na sua classe NotaFiscal:

// ...
for (Produto prod : this.items) {
   System.out.println("Produto: " + prod.getDescricao());
   System.out.println("Quantidade: " + prod.getQuantidade());
   System.out.println("Valor parcial: " + prod.getValorParcial());
}
// ...

Por isso frisei que sua classe ItemNota poderia morrer, pescou?[/quote]

não sei se é valido ter um campo quantidade na classe produto… se for uma Classe referente a uma tabela do BD como eu salvaria o seguinte:

–Pedido1
-produtos:

  • bolo de chocolate, quantidade: 30.
  • arroz, quantidade: 50.

–Pedido2
-produtos:

  • bolo de chocolate, quantidade: 50.
  • arroz, quantidade: 10.

em qual coluna de qual tabela eu salvaria as quantidades ??? na minha cabeça seria em uma tabela chamada Item_pedido(id_pedido,id_produto,quantidade);

se existe essa classe ai Produto…, que nome você colocaria na classe Produto, quando o usuário for adicionar mais produtos no sistema e não em um pedido. teria que ser o mesmo, porém a classe ja ficaria diferente da do BD… por ter o campo quantidade e então frameworks JPA…Hibernate não funcionariam. e seria estranho se ver uma com um campo perdido ali.

[quote=douglaskd]
não sei se é valido ter um campo quantidade na classe produto… se for uma Classe referente a uma tabela do BD como eu salvaria o seguinte:

–Pedido1
-produtos:

  • bolo de chocolate, quantidade: 30.
  • arroz, quantidade: 50.

–Pedido2
-produtos:

  • bolo de chocolate, quantidade: 50.
  • arroz, quantidade: 10.

em qual coluna de qual tabela eu salvaria as quantidades ??? na minha cabeça seria em uma tabela chamada Item_pedido(id_pedido,id_produto,quantidade);

se existe essa classe ai Produto…, que nome você colocaria na classe Produto, quando o usuário for adicionar mais produtos no sistema e não em um pedido. teria que ser o mesmo, porém a classe ja ficaria diferente da do BD… por ter o campo quantidade e então frameworks JPA…Hibernate não funcionariam. e seria estranho se ver uma com um campo perdido ali.[/quote]

Realmente vendo por esse lado…

Mas acho que vai depender da regra de negócio adotada, e nesse caso se ele utiliza quantidade em ItenNota, imagino se tratar de produtos contáveis (hd, computadores, etc).

No caso do “Bolo de chocolate” não vejo problema algum sua quantidade, tendo em vista uma confeitaria, eles podem muito bem produzir bolos e mantê-los em um estoque, já o “arroz” entendo como serviço e seu produto seria um “Pacote de arroz”.

Mas está ficando interessante a discussão, são pontos de vista diferentes, além disso não analisei a hipótese dos problemas que podem causar usando frameworks.

Opa beleza !

Caraca, agora fiquei na dúvida, foi me passado este padrão de classe por que vou aplicar padrão singleton nestas classes, então estava fazendo as classes o mais tosco possível rodando e aplicar Singleton. Depois de aplicado irei testar com Junit a classe de NotaFiscal.

Mas como você mesmo disse, eu também achei que ia morrer mesmo a classe ItemNota só tinha um atributo.

Muito show, vou fazer como você especificou.

Tentar ao menos, estou iniciando mas to achando bastante desafiador .Valeu pessoal pela ajuda.