Cos'è un processo semplice per progettare un sistema OOP prima di codificarlo?

10

Ogni volta che mi veniva richiesto di costruire un progetto, sono sempre riuscito a costruirlo, non progettando un piano o un progetto, ma dopo aver scritto una lezione che era necessaria, che ha arricchito l'intero progetto, costruendo dal basso verso l'alto. Ora so che questo non è il modo corretto di creare software, ma non è facile per me avvolgere la mia mente su ciò che viene chiamato Objected Oriented Analysis and Design. Riesco più facilmente a capire il design procedurale top-down, poiché consiste semplicemente nel suddividere i compiti in sotto-attività, cose che hanno la loro controparte nel codice, nelle funzioni. Ma l'analisi e il design orientato agli oggetti non riesco a capire facilmente, perché non capisco come si possa sapere di quali classi avranno bisogno e in che modo interagiranno, a meno che non sappiano come li codificheranno.

Per una volta che introduciamo il concetto di classi e oggetti nel processo di progettazione, non possiamo più progettare dall'alto in basso, perché non stiamo più distruggendo i nostri problemi in quelle cose che possono essere implementate come procedure. Invece, in base a ciò che ho letto sull'argomento, dobbiamo determinare quali classi sono necessarie e creare vari artefatti in Unified Modeling Language, che possiamo usare quando implementiamo il software. Ma questo tipo di processo di progettazione non lo capisco. Come si fa a sapere di quali classi avranno bisogno e in che modo interagiranno, a meno che non abbiano già concepito l'intero sistema?

Questo è il mio problema. Non capisco come progettare un sistema orientato agli oggetti, anche se capisco i concetti di programmazione orientata agli oggetti, e posso usare quei concetti in qualsiasi linguaggio di programmazione orientata agli oggetti che conosco. Quindi ho bisogno di qualcuno che mi spieghi quale processo semplice posso usare per progettare sistemi orientati agli oggetti in un modo che abbia senso per me.

    
posta gaxar 21.06.2017 - 05:34
fonte

6 risposte

20

Stile dall'alto verso il basso OOAD non garantisce che il codice che scrivi sia orientato agli oggetti. Ho visto montagne di codice prodotto rigorosamente OOAD che lo dimostra. Se OO ti sta confondendo, non cercare aiuto qui. Non lo troverai. OO NON richiede di progettare dall'alto verso il basso.

Se immergerti in una classe è come ti piace codificare, così sia. Lascia che ti dica un suggerimento. Procrastinare.

È incredibile quanto sia facile progettare le classi scrivendo il codice che le utilizza anche quando non esistono ancora. Dimentica la procedura. Dimentica la struttura. Prenditi un bel livello di astrazione coerente e seguilo. Non cedere alla tentazione e mescolare dettagli extra. Tutto ciò che ti porta fuori dall'astrazione attuale può essere fatto con un metodo che potrebbe essere su qualche altro oggetto che in qualche modo sa tutto ciò che deve sapere. Non costruire niente che puoi semplicemente chiedere di essere consegnato a te.

Impara a scrivere in questo modo e scoprirai che stai facendo OO senza nemmeno tentare molto. Questo ti costringe a guardare i tuoi oggetti dal punto di vista di come vengono utilizzati (la loro interfaccia) e quali oggetti conoscono quali altri oggetti. Indovina quali sono i due punti principali di un diagramma UML?

Se riesci a entrare in quella modalità di pensare, ciò che rimane è l'architettura. Lo stiamo ancora cercando. Da MVC a architettura pulita a progettazione basata su domini. Studili e gioca. Usa ciò che funziona. Se trovi qualcosa di affidabile al 100% torna e fammi sapere. Lo sto facendo da decenni e sto ancora cercando.

    
risposta data 21.06.2017 - 06:06
fonte
4

Sostieni di essere in grado di utilizzare tecniche orientate agli oggetti nel tuo codice, quindi sai già come progettare un sistema orientato agli oggetti , credo che il tuo problema sia più di una questione di quando , non se puoi o meno. Sembri a tuo agio con il design orientato agli oggetti in un modo iterativo a breve termine, invece di un modo di pianificazione a lungo termine.

Quando si sviluppa un progetto per la prima volta può essere molto difficile pianificare e progettare, questo è il momento in cui sviluppo agile è favorito rispetto allo sviluppo a cascata , come il grande ambito di un piano a cascata spesso non cattura tutte le complessità di un progetto software.

Asserisci che lo sviluppo al volo senza un "piano iniziale" è:

"... not the proper way to create software ..."

Se il tuo problema è che il tuo piano iniziale non è sufficientemente dettagliato, prenditi un po 'più di tempo per spiegare i tuoi primi pensieri. Qual è la prima parte del programma che hai intenzione di scrivere? Che cosa succederà a bisogno ? Forse non pensate nemmeno a quali oggetti iniziare, invece pensate a quali caratteristiche e piano da lì.

Se il tuo problema è che non sei sicuro delle tue capacità di documentare / progettare / UML , pratica documentando un progetto esistente.

Personalmente raccomanderei di non preoccuparsi del fatto che i tuoi progetti siano perfettamente orientati agli oggetti, la maggior parte dei sistemi non sono orientati agli oggetti al 100%. L'obiettivo è quello di creare una migliore comprensione e visualizzazione del sistema, non un'astrazione perfetta. L'orientamento all'oggetto non è il proiettile d'argento, è solo un altro strumento sul nastro.

    
risposta data 21.06.2017 - 11:30
fonte
2

OOAD è un'utopia. Con ciò non intendo che sia l'approccio migliore, voglio dire che non è mai veramente realizzabile a mio modesto parere. Nella mia esperienza, qualcosa cambia sempre, sia che si tratti di requisiti o specifiche, o anche di un conflitto di dipendenze che ti costringe a sostituire completamente una dipendenza. Che sia perché ho imparato in questo modo o perché è quello che mi viene più naturale, le mie idee per il design arrivano più facilmente mentre sto scrivendo il codice. Se sto per codificare e non ho una chiara idea di come strutturerò il codice, farò un punto per dedicare del tempo a capire veramente il problema prima, anche se il più delle volte, vedo il necessità per una classe e ce la farò.

Il mio consiglio è che la cosa migliore che puoi fare per te è il codice usando facciate , fornendo una semplice interfaccia per input e output, e sperare che gli input e gli output non cambino spesso. Anche se lo fanno, sanno che non si tratta di un problema di progettazione, quanto di un problema di specifiche (cambiamento di necessità / funzionamento / funzionalità). Ciò renderà il tuo programma piuttosto resistente ai problemi che risuonano all'interno del tuo programma verso coloro che chiamano il tuo programma o sezione di codice e viceversa.

Per quanto riguarda la progettazione di un sistema orientato agli oggetti, si dovrebbe dire qualcosa per cercare di rendere tutto orientato agli oggetti quando non dovrebbe essere. Questo è un errore comune tra i linguaggi di programmazione OOP come C # e Java è quello di provare a trattare tutto come un oggetto, che spesso si traduce nella creazione di una singola istanza di una classe per eseguire quelli che altrimenti sarebbero metodi statici che non cambiano stato di sorta. Detto questo, ovviamente dovresti usare il design OOP laddove applicabile, anche se non ti sembra che tu stia sbagliando quando è più naturale scrivere un metodo statico. Non è sempre l'istinto sbagliato.

Dovresti prendere in considerazione l'utilizzo di una classe quando rispondi affermativamente a una delle seguenti domande:

  • Ho un gruppo di informazioni relative allo stesso concetto (ad esempio nome, cognome, indirizzo)?
  • Devo eseguire un'operazione che richiede diverse informazioni (ad esempio calculatePrice(basePrice, quantity, tax) )?
  • Ho un altro se con blocchi di codice di grandi dimensioni eseguono operazioni leggermente diverse con informazioni uguali o simili (ad esempio if(type == "cat") { meow(name); } else if (type == "dog") { bark(name); } == > animal.speak() )
  • Ho una classe esistente che esegue più di un compito specifico e sta crescendo un po 'troppo grande?

Dopo un po ', diventerà una seconda natura per creare classi. Non aver paura di usarli se il tuo codice rientra in uno dei casi di cui sopra. Spero che questo aiuti!

    
risposta data 21.06.2017 - 11:29
fonte
2

Penso che i punti fatti da Doc Brown nei commenti meritino molta più visibilità di commento dato che ha assolutamente ragione:

"Now I know this is not the proper way to create software" - who told you this? It seems somehow you fall into the popular trap of believing "design is something what you do before coding, maybe by drawing fancy UML diagrams". To cure you from this misconception, I recommend to start with "Code as Design" by Jack Reeves. – Doc Brown Jun 21 at 5:27

@Laiv: "coding" is part of what in other engineer disciplines is called design. In house building, the step from design to the end product is done using pilling bricks and mortar. In programming, this step is done by the compiler when translating the design (=program) into the end product (=executable binary). And that is not a new wisdom. Reeves essays are 25 years old. – Doc Brown Jun 21 at 6:39

Questo stesso sentimento viene echeggiato anche in altri luoghi. Prendi in considerazione i colloqui di Glenn Vanderburg su "Real Software Engineering" e, in qualche misura, il suo "Artigianato, Ingegneria e Essenza della Programmazione" e " Colloqui di "Craft and Software Engineering". Considera inoltre WhatIsSoftwareDesign e TheSourceCodeIsTheDesign pagine / discussioni sul wiki C2.

Il concetto che il codice è il design non è specifico di alcun paradigma. Può essere applicato allo stesso modo a oggetti orientati, funzionali, procedurali, logici o qualsiasi altra cosa. L'idea alla base è la stessa: il design è il codice sorgente stesso. L'atto di costruzione è il processo mediante il quale il codice sorgente (il disegno) è trasformato in una cosa utilizzabile da un interprete o un compilatore.

In un sistema complesso, è probabile che ci sia un certo livello nella progettazione architettonica, identificando sottosistemi, componenti, moduli, servizi e assegnando loro i requisiti prima di iniziare a scrivere il codice. È possibile utilizzare UML come un modo per creare, documentare e aiutare nelle discussioni intorno a questo progetto architettonico. Considera l'idea delle modalità UML che Martin Fowler discute , in particolare UML come schizzo e UML come note . Considera anche alcune idee di Agile Modeling - Modellazione iniziale dell'architettura , Iteration Modeling e Solo modelli abbastanza buoni .

Tutto ciò significa che il modo giusto per creare software non è quello di dare corpo all'intero progetto. È sufficiente dedicare tempo sufficiente a comprendere i requisiti più critici (al momento attuale), identificare le dipendenze tecniche e i compromessi tra i requisiti, e quindi sfruttare il fatto che il software è morbido. Riconosciamo anche che il costo di prendere il tuo design e produrre qualcosa è incredibilmente basso (specialmente se paragonato a prendere un disegno e produrre qualcosa in molte altre discipline ingegneristiche). Quindi, esegui iterazioni sulle tue attività di progettazione (codifica) e approfitta di quanto è facile ed economico costruire progressivamente o modificare ciò che hai fatto.

    
risposta data 29.06.2017 - 14:59
fonte
1

OOAD riguarda l'identificazione di entità e la modellazione di oggetti o concetti di vita reale in un grado di astrazione. Lo percepirai come più semplice se invece di scrivere classi all'inizio di interfacce di scrittura, dato che non devi ancora implementarle, ma il codice viene compilato.

OOAD non esclude la possibilità di pensare nel sistema come grandi moduli. Puoi ancora farlo. Ogni modulo esiste per soddisfare una serie di user story (casi d'uso). Tali storie utente richiedono classi che collaborino per soddisfarle.

Una delle principali differenze tra gli approcci procedurali e OO è che solitamente i requisiti delle mappe di pensiero procedurali agli schermi, mentre l'OOD tende a pensare a cosa succede sotto la cappa lasciando il front end ad essere fatto da un'altra persona o in un non-OO moda.

C'è una tecnica in Extreme Programming chiamata Carte CRC . CRC sta per "class-responsibility-collaboratori".

Fondamentalmente si identificano classi evidenti e si assegna una carta a ciascuna. Supponi che la classe Invoice abbia la sua scheda.

Per ogni classe che tiene in mano scrivi quali sono le responsabilità di quella classe, ad esempio "calcola un totale complessivo" .

Anche per ogni classe di detenzione di carte, scrivi quali altre classi di cui la classe deve chiedere qualcosa per adempiere alle proprie responsabilità. Qui potresti scoprire che Invoice richiede la collaborazione di InvoiceDetail o addirittura scoprire che tale classe è necessaria in primo luogo.

Potresti scoprire che alcune responsabilità che pensavi appartenessero a Invoce , in realtà appartengono a uno dei suoi collaboratori.

Dopo l'esercizio, ogni carta diventa una classe, ogni responsabilità diventa un metodo e ogni relazione di collaborazione può diventare una composizione, un'agregazione o una semplice chiamata.

Questo esercizio può (e dovrebbe) essere fatto in un gruppo, in cui anche gli uomini d'affari si divertono.

Puoi saperne di più su questa tecnica in questi link:

link

link

Esempi di carte CRC:

    
risposta data 28.06.2017 - 13:23
fonte
0

La sfida principale per noi, come comunità di professionisti del software; più specificamente i professionisti del design orientato agli oggetti, è quello di materializzare tutti i nostri problemi / compiti in una parte di programmazione. Che si tratti di attività - rappresentate come funzioni o di attori dei compiti - rappresentati come interfacce / classi [guida verso OOAD]. Man mano che evolviamo le nostre abitudini di progettazione del software, acquisendo continuamente conoscenze su varie metodologie / strutture. Il nostro punto di vista diventa sempre più raffinato per distinguere chiaramente gli oggetti e quale oggetto svolgerebbe quale funzione.

Come per abbattere i tuoi problemi in sotto-problemi con la presenza di oggetti in giro, puoi comunque farlo comodamente, perché TU hai il controllo totale di tutti gli oggetti che vuoi essere presenti. Hai anche la comodità di trasmettere la natura e lo scopo ai tuoi oggetti e interfacce. Tutto quello che devi fare è visualizzare la dichiarazione del problema e pensare a quale scopo / funzionalità può essere impartito su quale oggetto.

Cercherò di spiegare ulteriormente con l'aiuto di un esempio della gamma di automobili e metterò in evidenza due diversi modi di visualizzare lo stesso modello di oggetto.

Fai un esempio del costruttore di automobili che si estende su varie categorie di automobili: veicoli commerciali, auto di consumo (berline, berline, station wagon) ecc.

Affinché il produttore abbia chiaramente una separazione di categoria e scopo, ci sono molti modi con cui possono creare delle classi.

  1. In base alla categoria (settore di mercato) del veicolo: veicolo pesante, veicolo di consumo [berlina, hatchback, station-wagon ecc.]

  2. Basato sulla capacità del motore e amp; modalità di guida: 800-1500 CC, > 1500 CC ecc.

Seguendo il modo migliore in cui il produttore può impartire individualmente le funzioni agli oggetti appartenenti a ciascuna di queste classificazioni, possono scegliere una struttura di oggetto sottostante appropriata e costruirvi sopra un modello.

    
risposta data 22.06.2017 - 08:45
fonte

Leggi altre domande sui tag