evoluir e nem quais serao todas as necessidades dos usuarios num futuroproximo. Na maioria das vezes, criar hierarquias mais flexiveis atraves deinterfaces e a melhor solucao.Apesar de interfaces nao permitirem a implementacao de metodos, issonao impossibilita prover assistencia aos programadores. Voce pode combinar asvirtudes das interfaces e classes abstratas para criar classes abstratas comesqueletos de implementacao para cada interface nao trivial que voce pretendeexportar. A API de Collections utiliza extensivamente esse recurso atraves desuas implementacoes padrao de AbstractCollection, AbstractList, AbstractSet eAbstractMap. //Skeletal Implementationpublicabstract class AbstractMapEntry implements Map.Entry { // Primitive operations public abstract K getKey(); public abstract V getValue(); // Entries in modifiable maps must overridethis method public VsetValue(V value) { throw new UnsupportedOperationException(); } // Implements the general contract ofMap.Entry.equals @Override public boolean equals(Object o) { if (o == this) return true; if (! (o instanceof Map.Entry)) return false; Map.Entry arg = (Map.Entry) o; return equals(getKey(), arg.getKey())&& equals(getValue(), arg.getValue()); } private static boolean equals(Object o1,Object o2) { return o1 == null ? o2 == null :o1.equals(o2); } // Implements the general contract ofMap.Entry.hashCode @Overridepublic int hashCode() { return hashCode(getKey()) ^hashCode(getValue()); } private static int hashCode(Object obj) { return obj == null ? 0 : obj.hashCode(); }}A grande vantagem dessa abordagem e que ela prove a assistencia dasclasses abstratas sem impor as restricoes de quando se define um tipo somenteatraves destas. Para muitos implementadores da interface a escolhe obvia e estendera classe esqueleto, porem isso e estritamente opcional. Se uma classe nao podeestender a implementacao esqueleto, ainda podera implementar a interface edelegar a execucao de seus metodos para uma instancia privada de uma classeinterna que estende da classe abstrata esqueleto (semelhante ao que foi feitono item 16). Para concluir, projete com cuidado suas interfaces. Uma vez que estafor disponibilizada, e quase impossivel altera-la. Voce tem que fazer certo daprimeira vez. Acrescentar um metodo tardiamente ira quebrar qualquer codigo quefaca uso da interface. Ter varios programadores na definicao das interfaces euma boa estrategia. Item 19 Use interfaces apenas paradefinir tiposNao usar interfaces como um container para acomodar constantes. // Constant interfaceantipattern - do not use!public interfacePhysicalConstants {// Avogadro's number(1/mol)static final doubleAVOGADROS_NUMBER = 6.02214199e23;// Boltzmann constant (J/K)static final doubleBOLTZMANN_CONSTANT = 1.3806503e-23;// Mass of the electron(kg)static final doubleELECTRON_MASS = 9.10938188e-31;}Esse e um exemplo de mal uso de interfacesItem 20 Prefira hierarquia de classes ausar flagsE comum encontrarmos implementacoes inexperientes onde o comportamentode uma classe e regido pelo valor de uma flag. Essa flag geralmente e passadacomo parametro no construtor e vai decidir o comportamento da classe dentro deseus metodos. Os metodos terao comandos ifou switch em cada um dos valorespossiveis que a flag pode assumir. Esse tipo de artificio e uma forma muito pobre de simular hierarquiade classes, um dos principais conceitos da orientacao a objetos. Item 21 Use function objects para representar estrategias Algumaslinguagens provem maneiras para referenciar funcoes. Isso e util, por exemplo,para implementar o design pattern Strategy. Um metodo pode receber um ponteiropara uma funcao a qual sera chamada para executar alguma estrategia especifica.Uma classe que realiza ordenacao poderia ser implementada dessa forma,recebendo como parametro uma funcao com a implementacao da estrategia