Did Dijkstra ha intenzione di modularizzare il codice, quando ha scritto sulla separazione delle preoccupazioni?

9

Per prima cosa, ho letto un estratto di "Sul ruolo del pensiero scientifico" del 1974 di Edsger W. Dijkstra:

Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one's subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained —on the contrary!— by tackling these various aspects simultaneously. It is what I sometimes have called "the separation of concerns", which, even if not perfectly possible, is yet the only available technique for effective ordering of one's thoughts, that I know of. This is what I mean by "focusing one's attention upon some aspect": it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect's point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.

Vedo che la moderna separazione delle preoccupazioni parla della modularizzazione del codice. Tuttavia, leggendo la citazione di cui sopra, capisco questo come concentrando la tua mente su un particolare compito alla volta, mentre non si concentra su altri aspetti. Questo non significa necessariamente che il codice debba essere separato in blocchi modulari.

Cioè, diciamo che c'è un codice davanti a te che in un file ha i concetti di vista, repository, controller, gestione degli eventi, factory, ecc. tutto in un unico file.

Per un breve esempio, ecco un codice che ha accesso ai dati e visualizza (output):

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

Utilizzando l'OO moderno potrei inserire l'accesso ai dati nel proprio file utilizzando il modello di repository, il codice View può andare nel proprio modello di file e io posso collegarli insieme per comunicare tramite un controller (o Action o Gestore richieste), e posso aggiungere una fabbrica per creare e collegare varie dipendenze. E posso avere un file di configurazione che definisce quelle fabbriche. Sicuramente è a un passo dal single-file-tutto.

La mia domanda sulla separazione delle preoccupazioni è così: leggendo la citazione di Dijkstra, ho avuto l'idea che forse non intendeva necessariamente separare le preoccupazioni dalla "separazione modulare del codice (in file o nelle loro proprie funzioni / metodi / ecc. ) ", e che intendeva di più focalizzare la propria mente su un aspetto del programma, senza appesantire se stessi concentrandosi su altri aspetti importanti ma non ancora da considerare, indipendentemente dal fatto che siano fisicamente separati nel codice, o no.

Perché allora ci stiamo affliggendo con la separazione fisica dei codici e i modelli di progettazione? Non sarà sufficiente concentrarsi su un aspetto, indipendentemente da come è strutturato il tuo codice?

Non sto parlando di scrivere il codice di spaghetti più orribile e quindi solo considerando un aspetto di esso, questo sarebbe probabilmente un peso. Ma alla fine, quello che sto facendo è, perché eseguire la separazione fisica del codice, perché dividere il codice in file o blocchi separati (metodi), quando non è necessario focalizzarsi mentalmente su un aspetto?

La separazione delle preoccupazioni dovrebbe rimanere un esercizio mentale, piuttosto che fisico?
In altre parole, dovrebbe esserci una disconnessione tra gli aspetti mentali (messa a fuoco su) e quelli fisici (codice su carta) della programmazione?

    
posta Dennis 18.09.2018 - 17:24
fonte

6 risposte

13

Separazione dei dubbi è un modo astratto di pensare che consiste nel considerare separatamente cose che non devono essere correlate.

Modularizzazione (separando un gruppo non correlato di funzioni in moduli), incapsulamento (nascondendo i dettagli interni dei moduli) e astrazione (separando il generale dallo specifico e il idea dalla sua implementazione) sono tutti mezzi per implementare questo modo di pensare nel campo del design del software.

    
risposta data 18.09.2018 - 19:35
fonte
8

Suggerirei che, sebbene il documento sia di interesse storico, ciò che Dijkstra intendeva con il termine "separazione delle preoccupazioni" più di 40 anni fa non è particolarmente rilevante oggi. Al giorno d'oggi è ampiamente utilizzato in riferimento alla modulazione.

Ci sono molte prove che la modulazione è estremamente benefica e che i benefici superano di gran lunga i "carichi" che ci pongono. Qualunque cosa significasse Dijkstra allora, non cambia il fatto che piccoli pezzi di codice, ognuno focalizzato su una sola cosa, porta a un codice che è più facile da scrivere, leggere, capire, mantenere e testare.

    
risposta data 18.09.2018 - 18:38
fonte
2

Dijkstra sta facendo una dichiarazione esplicita su come pensare. La modularizzazione del programma (e del processo) - e la sua desiderabilità - è forse il risultato di quel pensiero, ma il punto chiave che sta facendo è come valutare un problema. Il programma è in genere la soluzione a un problema e, sostenendo una "separazione delle preoccupazioni", offre consigli saggi. Il miglior esempio di questo è forse "ottimizzazione". La battuta era: "Quando pianifichi di ottimizzare un programma, la tua prima strategia dovrebbe essere: non farlo". In altre parole, si desidera concentrarsi innanzitutto sulla corretta esecuzione del programma. Rendendolo veloce e di fantasia è una preoccupazione che dovrebbe essere separata, ma anche non completamente rimossa.

    
risposta data 18.09.2018 - 22:22
fonte
2

Posso darti un esempio personale di separazione delle preoccupazioni che penso sia paragonabile ai concetti di Dijkstra. Quando analizzo un particolare argomento nel software, costruisco tre viste.

  1. Innanzitutto considero i dati. I dati rappresentano i predicati logici del problema. Le classi sono costruite per astrarre entità nel mondo reale, con i loro attributi che sono i parametri dell'astrazione. Le associazioni tra classi rappresentano associazioni funzionali tra le istanze di classe. Non vi è alcun codice coinvolto nel pensiero a questo punto e nessun concetto di elaborazione. Solo una visione statica della logica coinvolta nell'argomento.
  2. Secondo, considero le dinamiche. Qualsiasi classe che abbia un ciclo di vita non banale è modellata come una macchina a stati finiti. Ciò comporta considerazioni sull'esecuzione e sulla sincronizzazione del sequenziamento. Di nuovo, nessun codice funziona solo come le cose interagiscono e in sequenza.
  3. Terzo, considero l'elaborazione. Qui, l'effettivo lavoro algoritmico che deve essere eseguito su transizioni di stato o in altre operazioni sincrone.

Alla fine, si ottiene una visione a tre facce dell'argomento che può quindi essere formulata come codice in qualunque raggruppamento sia conveniente per il codice stesso e per la sua manutenzione. Le tre sfaccettature non sono solo un esercizio mentale. Produco descrizioni scritte di tutte le sfaccettature. Perché? Perché se l'argomento è abbastanza grande, non riesco a contenere nemmeno un aspetto completo nella memoria a breve termine. Se l'argomento è piccolo, quasi tutti gli approcci funzioneranno perché puoi tenerlo tutto in testa.

La motivazione per separare le preoccupazioni è di accogliere i limiti di memoria a breve termine degli esseri umani. Semplicemente non possiamo portare tutto in testa allo stesso tempo, anche se i programmatori di computer tendono ad essere più capaci della maggior parte degli altri al numero di concetti che possono manipolare nella loro memoria a breve termine. Per essere efficaci, separare i dubbi deve sistematicamente escludere uno o più aspetti di un problema al fine di concentrarsi su qualche altro aspetto particolare. Ovviamente, escludendo un aspetto non scompare dalla considerazione. Ci deve essere un modo per combinare tutti gli aspetti problematici per ottenere una soluzione. L'esperienza mostra che spesso il risultato finale di separare e ricombinare i raccolti è una soluzione più comprensibile rispetto a un singolo balzo gigantesco in cui molti aspetti potrebbero essere mescolati insieme. Questo è particolarmente vero quando la dimensione del problema è grande o complessa.

    
risposta data 18.09.2018 - 19:07
fonte
1

La separazione delle preoccupazioni è un concetto logico che si propagherà nel tuo modello di organizzazione del codice, indipendentemente dal modo in cui lo implementa. È vero che un file di codice è solo un dettaglio tecnico, un modo per mantenere il software gestibile. Un singolo file con un buon editor che consente di comprimere un'espansione delle regioni potrebbe funzionare anche per te (per un po '). Oppure un database relazionale che memorizza classi e metodi in modo genitore-figlio in tabelle separate potrebbe funzionare come supporto di memorizzazione. Ma i file di testo sono difficili da battere in un mondo in cui il codice sorgente deve essere

  • portatile
  • accessibile da molti strumenti esterni diversi
  • accessibile da più programmatori
  • versionable and comparable
  • si adatta bene ai sistemi operativi che sono molto bravi nei file la manipolazione

La linea di fondo è che noi umani non siamo molto bravi a pensare oa trattare con cose diverse contemporaneamente. Quindi abbiamo bisogno di un modello che permetta di pensare e lavorare su una cosa alla volta senza il pericolo di rovinare un'altra parte che non stiamo considerando in quel momento. Così costruiamo, posando un mattone alla volta, assicurandoci che i mattoni che abbiamo posato prima non interferiscano con i mattoni posati più tardi. E se vogliamo cambiare un mattone in un secondo momento, le cose non devono crollare. Questo è un modello che funziona per le nostre menti a una sola traccia.

Questo non è il modo in cui crescono funghi o alghe ... Come si fa per un fatto umiliante?

    
risposta data 18.09.2018 - 21:39
fonte
-1

Credo che la risposta specifica alla citazione di Dijkstra sia stata affrontata, tuttavia, poiché dichiari che "Utilizzando l'OO moderno potrei inserire l'accesso ai dati nel proprio file" e chiedo "La separazione delle preoccupazioni rimane un esercizio mentale, piuttosto che fisico? " lascia che attiri la tua attenzione su dove i direttori di OO moderni ci dirigono.

Si dovrebbe seguire i principi SOLID nello sviluppo usando OO. Ecco un bel link per loro, ma il TLDR su "separazione delle preoccupazioni" è principalmente nella S in SOLID: Il principio di responsabilità singola o SRP.

Questo, sicuramente, è un esercizio fisico, non mentale. Per il tuo esempio specifico, MVC (oi suoi fratelli MVVM e MVP) indirizzano uno a fisicamente a separare i concerti di Model, View e Controller / Presenter / ViewModel in file separati. Ho visto alcune implementazioni MVVM in cui queste sono implementate in assembly separati per limitare ulteriormente la tendenza a "confondere i concetti".

Ma. Va oltre semplice "questa è una visione e questo è un modello", se segui la la vista dello zio Bob su questo.

È necessario considerare anche la fonte dei requisiti per ogni particolare elemento OO. Se stai mixando, ad esempio, ciò che il Cliente vuole con ciò che il personale operativo vuole, stai anche violando l'SRP. Oppure, per dirla come fa lo zio Bob: una classe dovrebbe avere uno e un solo motivo per cambiare.

Consiglio vivamente di continuare a cercare ulteriormente utilizzando i collegamenti forniti o di eseguire una ricerca sul Web per "principi solidi".

    
risposta data 18.09.2018 - 22:50
fonte