Come per qualsiasi regola, penso che la cosa importante qui sia considerare lo scopo della regola, lo spirito, e non impantanarsi nell'analizzare esattamente come la regola è stata formulata in alcuni libri di testo e come applicarla in questo caso. Non abbiamo bisogno di avvicinarci a questo tipo di avvocati. Lo scopo delle regole è aiutarci a scrivere programmi migliori. Non è come lo scopo di scrivere programmi è quello di mantenere le regole.
Lo scopo della regola della responsabilità unica è di rendere i programmi più facili da capire e da mantenere facendo sì che ciascuna funzione faccia una cosa autonoma e coerente.
Ad esempio, una volta ho scritto una funzione che ho chiamato qualcosa come "checkOrderStatus", che determinava se un ordine era in sospeso, spedito, back-ordinato, qualunque cosa e restituiva un codice che indica quale. Poi è arrivato un altro programmatore che ha modificato questa funzione per aggiornare anche la quantità a disposizione al momento della spedizione dell'ordine. Ciò ha gravemente violato il principio della responsabilità unica. Un altro programmatore che legge quel codice in seguito vedrebbe il nome della funzione, vedere come è stato usato il valore di ritorno e potrebbe non sospettare mai che abbia fatto un aggiornamento del database. Qualcuno che aveva bisogno di ottenere lo stato dell'ordine senza aggiornare la quantità a disposizione sarebbe in una posizione scomoda: dovrebbe scrivere una nuova funzione che duplica la parte dello stato dell'ordine? Aggiungi un flag per dire se fare l'aggiornamento db? Ecc. (Ovviamente la risposta corretta sarebbe quella di interrompere la funzione in due, ma ciò potrebbe non essere pratico per molte ragioni.)
D'altra parte, non farei il pasticcio di ciò che costituisce "due cose". Recentemente ho scritto una funzione che invia informazioni sui clienti dal nostro sistema al sistema del nostro cliente. Quella funzione esegue una riformattazione dei dati per soddisfare i loro requisiti. Ad esempio, abbiamo alcuni campi che potrebbero essere nulli sul nostro database, ma non consentono null, quindi dobbiamo inserire un testo fittizio, "non specificato" o ho dimenticato le parole esatte. Probabilmente questa funzione sta facendo due cose: riformattare i dati e inviarli. Ma ho intenzionalmente messo questo in una singola funzione piuttosto che avere "riformattare" e "inviare" perché non voglio mai, mai inviare senza riformattare. Non voglio che qualcuno scriva una nuova chiamata e non si rende conto che deve chiamare reformat e quindi inviare.
Nel tuo caso, aggiorna il database e restituisci un'immagine del record scritta come due cose che potrebbero andare insieme logicamente e inevitabilmente. Non conosco i dettagli della tua applicazione, quindi non posso dire definitivamente se questa è una buona idea o no, ma sembra plausibile.
Se si sta creando un oggetto in memoria che contiene tutti i dati per il record, facendo le chiamate al database per scrivere questo e quindi restituendo l'oggetto, questo ha molto senso. Hai l'oggetto nelle tue mani. Perché non restituirlo? Se non hai restituito l'oggetto, come potrebbe ottenere il chiamante? Doveva leggere il database per ottenere l'oggetto che hai appena scritto? Sembra piuttosto inefficiente. Come avrebbe trovato il disco? Conosci la chiave primaria? Se qualcuno dichiara che è "legale" che la funzione di scrittura restituisca la chiave primaria in modo da poter rileggere il record, perché non restituire semplicemente l'intero record in modo da non doverlo? Qual è la differenza?
D'altra parte, se la creazione dell'oggetto è un po 'di lavoro abbastanza diverso dalla scrittura del record del database, e un chiamante potrebbe voler scrivere ma non creare l'oggetto, questo potrebbe essere uno spreco. Se un chiamante potrebbe volere l'oggetto ma non scrivere, allora dovresti fornire un altro modo per ottenere l'oggetto, il che potrebbe significare scrivere codice ridondante.
Ma penso che lo scenario 1 sia più probabile, quindi direi, probabilmente nessun problema.