Questa domanda è importante per me nella crescita delle mie capacità tecniche. Trovo che oscilli da capo a punto, come un pendolo, scrivendo un codice che è allo stesso tempo ASCIUTTO ma leggibile & efficiente. E lo faccio costantemente ... il che porta a troppi fattori di ri-determinazione e mai a una risoluzione soddisfacente.
Il vero esempio è un carrello di e-commerce, in cui hai due azioni di base: add_item
e remove_item
. Entrambe le azioni eseguono le seguenti operazioni, regolano un item_counter
utilizzato per calcolare un total_price
(che viene mostrato nella vista), aggiungi / rimuovi un cart_item
nella vista.
Inizialmente, ho cercato il codice più semplificato possibile, quindi ho finito per sembrare:
$(".item").click(function() {
type_of_operation = $(this).data("type") // can be add or remove
item_id = $(this).data("id")
doOperation(type_of_operation, item_id)
})
function doOperation(type_of_operation, item_id) {
count = toggleItemCounter(type_of_operation)
updatePrice(count)
toggleCartItem(type_of_operation, item_id)
}
function toggleItemCounter(type_of_operation) {
old_count = JSON.parse(sessionStorage.getItem("counter")
if (type_of_operation == "add") {
new_count = old_count + 1
} else if (type_of_operation == "remove") {
new_count = old_count - 1
}
return new_count
}
function updatePrice(count) {
price = count * 10
$("#total_price").text(price)
}
function toggleCartItem(type_of_operation, item_id) {
if (type_of_operation == "add") {
item = "<div class='item' data-type='remove' data-id='item_id'></div>"
$("#item-list").append(item)
} else if (type_of_operation == "remove") {
$("#item-list").find("[data-id='"+item_id+"']").remove()
}
}
Man mano che la base di codice cresceva, mi sono reso conto che ci sono alcune attività eccezionali per aggiungere / rimuovere e alcuni item_ids, quindi una funzione, ad esempio, è cresciuta in qualcosa del genere:
function doOperation(type_of_operation, item_id) {
if (item_id = 999) {
specialPriceUpdate()
} else {
if (type_of_operation == "modify") {
adjustCartItem(item_id)
} else {
count = toggleItemCounter(type_of_operation)
updatePrice(count)
toggleCartItem(type_of_operation, item_id)
}
}
}
Questa crescita continuò come un tumore fino a quando doOperation
divenne ingombrante e molto difficile da leggere, con nidi di condizionali e ritorni speciali e così via. Mi resi conto che la mia rovina era che cercavo di rendere tutto "generico" quando avrei dovuto essere più specifico. Quindi, in un refactoring, ho riscritto quanto sopra a qualcosa del genere:
$(".add_item").click(function() {
item_id = $(this).data("id")
count = addItemCounter()
updatePrice(count)
addCartItem(item_id)
}
$(".remove_item").click(function() {
item_id = $(this).data("id")
count = reduceItemCounter()
updatePrice(count)
removeCartItem(item_id)
}
$(".modify_item").click(function() {
item_id = $(this).data("id")
adjustCartItem(item_id)
}
$(".special_item") {
specialPriceUpdate()
}
function addItemCounter() {
old_count = JSON.parse(sessionStorage.getItem("counter")
return old_count + 1
}
function reduceItemCounter() {
old_count = JSON.parse(sessionStorage.getItem("counter")
return old_count - 1
}
function updatePrice(count) {
// same as previous
}
function addCartItem(item_id) {
item = "<div class='item' data-type='remove' data-id='item_id'></div>"
$("#item-list").append(item)
}
function removeCartItem(item_id) {
$("#item-list").find("[data-id='"+item_id+"']").remove()
}
function adjustCartItem(item_id) {
$("#item-list").find("[data-id='"+item_id+"']").append("some adjustment")
}
E poi ho pensato, ok che sembra più chiaro e leggibile. Ma poi (perché il vero esempio ha più funzioni), ero come ... beh, aspetta un minuto, in genere segui sempre lo stesso schema: aggiungendo o rimuovendo il contatore, aggiornando il prezzo, quindi aggiungendo o rimuovendo l'oggetto, quindi forse dovrebbe esserci un% co_de unificato e una funzione add
unificata, quindi qualcosa come ...
function addItem(item_id) {
count = addItemCounter()
updatePrice(count)
addCartItem(item_id)
}
function removeItem(item_id) {
count = reduceItemCounter()
updatePrice(count)
removeCartItem(item_id)
}
E conoscendo me stesso, una volta che sarò a quel punto, lo guarderò e penso, per gol remove
e addItem
sono fondamentalmente uguali, tranne che per l'aggiunta e la rimozione di uno! Perché non lo collasso semplicemente in una singola funzione con una serie di interruttori e quindi alcuni condizionali per consentire le eccezioni? Sì, e poi questo mi riporta al punto 1 ...
Vedi, a differenza di un pendolo, non smetto mai di oscillare da una parte all'altra per raggiungere una sorta di buona via di mezzo. Letteralmente potrei girare e girare in tondo ogni volta che mi siedo per riesaminare il codice. La mia mente è fondamentalmente come ... "le grandi funzioni di dio sono più efficienti ... per ... non c'è modo, hanno bisogno di funzioni ben distinte per tutto ... per ... hmm sembra che queste funzioni distinte potrebbero essere un po 'più secche, asciugiamole .. per ... ok bene li ho asciugati ancora una volta in una grande funzione di dio ... "
Penso che parte di esso sia che non sono sicuro di attenermi a una soluzione, perché c'è così tanto contesto su ciò che è "ottimale". In parte è che sono autodidatta, quindi non ho i principi guida per dire veramente, OK smetti di oscillare, questa è la regola pratica appropriata da seguire.
Questo / è successo a te? Cosa fai ?? !!