Molto tempo fa ho chiesto sull'utilizzo di un enum per usare essenzialmente come una versione povera di instanceof
per prendere decisioni su un oggetto.
Come indicato in questa risposta:
When your weapon types enum just mirrors the class hierarchy, then this is a blatant violation of the DRY principle - you encode the same information, the type of a weapon redundantly in two places - one place is the class name itself, one place the enum. That's definitely not just a code smell, that is bad code.
Ho quindi mi sono chiesto a proposito di avere un List
o un Map
che conteneva una raccolta di attributi che l'oggetto poteva contenere e che utilizzava un metodo, vorrei chiedergli quali attributi conteneva e quindi procedere a lavorare con quell'oggetto.
Mettiamo da parte l'idea Collection
per ora, perché voglio concentrarmi su un altro problema correlabile.
In Clean Code, P.19 il seguente frammento di codice è fornito come un buon esempio di metodi e variabili ben denominati.
public List<Cell> getFlaggedCells(){
List<Cell> flaggedCells = new ArrayList<Cell>();
for(Cell cell : gameboard){
if(cell.isFlagged()){
flaggedCells.add(cell);
}
}
return flaggedCells;
}
Da questo frammento di codice, sappiamo che un cell
contiene un metodo che verifica se è stato contrassegnato. In altre parole, possiamo chiedere alla cella, sei contrassegnato?
Raccogliamo quindi un List
di celle contrassegnate e torniamo al chiamante.
Nella mia seconda domanda, ho avuto il seguente frammento di codice:
public abstract class Weapon
{
private List<GameObjectAttributes> gOAttributes;
// imagine a constructor :D.
public final boolean containsAttribute(GameObjectAttributes attribute)
{
// determine if weapon contains a specific attribute.
}
}
Una classe Wizard potrebbe apparire come questa:
public Wizard extends Character {
private List<Weapons> weapons;
public boolean tryAdd(Weapon weapon){
if !(weapon.containsAttribute(WeaponType.LongBlade)){
return weapons.add(weapon);
}
return false;
}
}
Molto simile allo snippet Clean Code, sto chiedendo l'oggetto, conterrai un attributo specifico e, in caso contrario, aggiungilo alla raccolta weapons
.
Come indicato in questo link , utilizzando una enum
per mappare i comportamenti polimorfici è un odore di codice, e giustamente. Lo stesso avviso è dato nel mio secondo link in alto.
Domanda:
Perché l'esempio del codice pulito è considerato soddisfacente, utilizzando un attributo interno per filtrare gli oggetti, ma quando uso una mappa per filtrare in base agli attributi, è considerato odore di codice?
Sono non che verifica un attributo specifico e poi chiamo un metodo per eseguire un'azione, sto semplicemente filtrando, niente di più, niente di meno.