Ok, vamos mostrar como eu faria. Para começar, eu separaria as classes Telefone e Email. Afinal, são dados com regras próprias. O telefone divide-se por tipos, portanto, também criaria um enum para representar os tipos de telefone.
Depois, alteraria a classe de contatos para refletir essas mudanças:
Arquivo Email.java
package br.com.lojavirtual.www.classes.uteis;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class Email {
private String email;
public static boolean validar(String email) {
if (email == null || email.length() < 1) {
return false;
}
/*
* Padrão de email : Pode começar com letras de a até z maiusculo e
* minusculo Pode começar com numeros 0 ate 9 Deve ter apenas um @ pode
* ter um ou mais . pode conter _.- Deve conter de 2 a 4 letras no final
*/
Pattern padrao = Pattern
.compile("[a-zA-Z0-9]+[a-zA-Z0-9_.-]+@{1}[a-zA-Z0-9_.-]*\.+[a-z]{2,4}");
Matcher valida = padrao.matcher(email);
return valida.matches();
}
public Email(String email) {
setEmail(email);
}
public void setEmail(String email) {
if (!Email.validar(email)) {
throw new IllegalArgumentException("E-mail inválido!");
}
this.email = email;
}
public String getEmail() {
return email;
}
}
Arquivo Telefone.java
package br.com.lojavirtual.www.classes.uteis;
public final class Telefone {
private String codigoArea;
private String telefone;
private TipoTelefone tipo;
public Telefone(TipoTelefone tipo, String codigoArea, String telefone) {
this.tipo = tipo;
setCodigoArea(codigoArea);
setTelefone(telefone);
}
public void setTelefone(String telefone) {
if (!tipo.validarTelefone(telefone)) {
throw new IllegalArgumentException("Telefone inválido!");
}
this.telefone = telefone;
}
public void setCodigoArea(String codigoArea) {
if (!tipo.validarCodigoArea(codigoArea)) {
throw new IllegalArgumentException("Codigo de área inválido!");
}
this.codigoArea = codigoArea;
}
public String getCodigoArea() {
return codigoArea;
}
public String getTelefone() {
return telefone;
}
public TipoTelefone getTipo() {
return tipo;
}
}
Arquivo TipoTelefone.java
package br.com.lojavirtual.www.classes.uteis;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public enum TipoTelefone {
/**Padrao Telefone Fixo<p>
* <ul>
* <li>Deve começar com numeros de 2 ate 6
* <li>Deve ter no máximo 8 caracteres
* </ul>
*/
FIXO("[1-9][0-9]", "[2-6]{1}[0-9]{7}"),
/** Padrao Telefone Celular.<p>
* <ul>
* <li>Deve começar com numeros de 6 ate 9
* <li>Deve ter numeros de 0 ate 9
* <li>no máximo 8 caracteres
* </ul>
*/
CELULAR("[1-9][0-9]", "[6-9]{1}[0-9]{7}");
private String patternCodigoArea;
private String patternTelefone;
private TipoTelefone(String patternCodigoArea, String patternTelefone) {
this.patternCodigoArea = patternCodigoArea;
this.patternTelefone = patternTelefone;
}
public boolean validarTelefone(String telefone) {
if (telefone.length() < 7) {
return false;
}
Pattern padrao = Pattern.compile(patternTelefone);
Matcher valida = padrao.matcher(telefone);
return valida.matches();
}
public boolean validarCodigoArea(String codigoArea) {
Pattern padrao = Pattern.compile(patternCodigoArea);
Matcher valida = padrao.matcher(codigoArea);
return valida.matches();
}
}
Arquivo Contato.java
package br.com.lojavirtual.www.classes.uteis;
public abstract class Contato {
private int id;
private Email email;
private Telefone fixo;
private Telefone celular;
//Não coloque construtor padrão se vc tem dados obrigatórios, como o id.
public Contato(int id)
{
this.id = id;
}
public Contato(int id, Email email, Telefone fixo, Telefone celular)
{
this(id);
if (fixo.getTipo() != TipoTelefone.FIXO)
throw new IllegalArgumentException("Informe um telefone fixo!");
if (celular.getTipo() != TipoTelefone.CELULAR)
throw new IllegalArgumentException("Informe um telefone fixo!");
this.email = email;
this.fixo = fixo;
this.celular = celular;
}
public int getId() {
return id;
}
public Telefone getFixo() {
return fixo;
}
public Telefone getCelular() {
return celular;
}
public void setFixo(Telefone fixo) {
if (fixo.getTipo() != TipoTelefone.FIXO)
throw new IllegalArgumentException("Informe um telefone fixo!");
this.fixo = fixo;
}
public void setCelular(Telefone celular) {
if (celular.getTipo() != TipoTelefone.CELULAR)
throw new IllegalArgumentException("Informe um telefone celular!");
this.celular = celular;
}
public void setEmail(Email email)
{
this.email = email;
}
public Email getEmail() {
return email;
}
}
Note que com blocos menores, ficaria muitíssimo fácil incluir um novo tipo de telefone. Bastaria incluir um tipo a mais no enum.
Também seria fácil alterar o contato para ter mais telefones. Ou para que o usuário especifique 2 telefones, de qualquer tipo (para, por exemplo, na falta de um celular, o Contato ter dois fixos, o de casa e o da empresa).
Não fiquei muito convencido de que os métodos de validação de telefone tenham que testar o length(). Talvez fosse melhor deixar esse trabalho para a expressão regular. Note que também reduzi código ao eliminar seus ifs com atributos booleanos (como no caso do matches()). Você testava "se matches() é true, retorna true, senão, se matches() é false, retorna false". Ora, é mais fácil retornar matches de uma vez!
Outra coisa... Também pode-se reduzir código e identação se, sempre que seu if disparar uma exceção ou tiver um "return", você eliminar o else.
Classes menores também se tornam mais coesas e reaproveitaveis. Se no futuro você criar uma classe para empresas, provavelmente poderá reusar os tipos Telefone e Email. Aliás, você pode até mesmo separar esses tipos num outro .jar, e usar em diversos projetos, além do da loja virtual.
A dica é, não tenha medo de criar classes. É muito melhor ter um conjunto de classes pequenas e coesas, do que ter uma hierarquia de uma classe só enorme.