A loop-switch szekvencia, avagy for-case paradigmaThe FOR-CASE paradigm and Switched on Loops at The Daily WTF egy programozási antiminta, ahol egy lépéssorozatot egy ciklus belsejében elhelyezett switch valósít meg, mintha nem lenne ismert az egyes lépések sorrendje. A spagetti kód speciális esete.
Ha egy ciklusban switch van, az még nem biztos, hogy antiminta. Csak akkor tekinthető annak, ha a lépések sorrendje ismert. A korrekt megvalósításra példa a kontroll megfordítása, és egy eseménykezelő működtetése. Az eseménykezelő ciklusokban a lépések sorrendje ismeretlen fordítási időben, mivel azokat a felhasználó választja ki. Emiatt a switch valóban szükséges. Lásd: eseményvezérelt programozás, eseménykezelő ciklus, és eseményvezérelt véges állapotú gép.
A kigöngyölített ciklus hiánya okozhat gyengébb performanciát, habár ez nem mindig érződik. Mégsem a performancia gyengítése, hanem a rosszabb olvashatóság a minta legfontosabb következménye. Minden nem triviális példában nehezebb megérteni a programrészletet, annak célját és működését, mint egy szekvenciát tartalmazó ciklust. Példa A következő példa egy megfigyelő interfészt valósít meg: String key = null; String value = null; List<String> params = null; int column = 0;
public void addToken(token) {
// parse a key, a value, then three parameters switch (column) { case 0: params = new LinkedList<String>(); key = token; break; case 1: value = token; break; default: params.add(token); break;
if (++column >= 5) { column = 0; completeRow(key, value, params);
Az eseménykezelő nélkül ez antiminta:
// parse a key, a value, then three parameters String key = null; String value = null; List<String> params = new LinkedList<String>();
for (int i = 0; i < 5; i++) { switch (i) { case 0: key = stream.parse(); break; case 1: value = stream.parse(); break; default: params.add(stream.parse()); break;
A refraktorált megoldás: // parse a key and value String key = stream.parse(); String value = stream.parse();
// parse 3 parameters List<String> params = new LinkedList<String>(); for (int i = 2; i < 5; i++) { // in practice, that might be written as (i = 0; i < 3; i++), // but for illustration we use the same range of indices here // as in the switch above; the fact that the loop body does // not actually use the value of i proves that the // loop-and-switch construct was superfluous in the example above. params.add(stream.parse()); }
Jegyzetek
Fordítás
Kategória:Programozási antiminták