Ereditarietà come specializzazione

1

Ho una classe chiamata Libro con campi come titolo, tipo ecc. Ho anche una classe chiamata Libreria che gestisce i libri.

La libreria ha metodi che:

  • Aggiungi una copia di un libro su uno scaffale
  • Spostare una copia di un libro da uno scaffale a un altro

Come posso gestire il fatto della copia del libro?

Una soluzione è creare una sottoclasse di Book, ad esempio BookCopy.

C'è una soluzione migliore?

    
posta Cenzy 15.04.2018 - 18:59
fonte

5 risposte

2

Non è necessariamente utile tradurre i concetti del mondo reale troppo direttamente in un modello a oggetti. Nel mondo reale, un "libro" e una "copia di un libro" sembrano essere la stessa cosa. Forse dovremmo creare una classe di libri e le copie sono esempi di quella classe? No.

Sembra un "libro" e una "copia di un libro" sono concetti diversi nel tuo dominio problematico. Un libro può avere molte copie. Entrambi i concetti dovrebbero essere rappresentati nel modello dell'oggetto. Potrebbe quindi essere sensato creare due classi diverse. Ad esempio:

// represent an abstract published book
class Book {
  String author;
  String title;
  Date publication;
  ISBN isbn;
}

// represent a copy of a book that can be lent out
class BookCopy {
  Book book;
  CatalogNumber id;
  Optional<User> currentlyLentOutTo;
  int shelf;
}

Perché non usare l'ereditarietà? Se si utilizza l'ereditarietà, la copia del libro conterrà tutti i campi del libro direttamente. Quindi non possiamo rispondere a domande come "quante copie abbiamo di questo libro" senza confrontare tutti i contenuti degli oggetti. Rappresentare concetti diversi come classi diverse di solito è meglio.

Le buone pratiche OOP scoraggiano strongmente l'uso eccessivo dell'ereditarietà. Risulta che l'ereditarietà è spesso il problema e non la soluzione. Come linea guida approssimativa: l'ereditarietà tende a essere usata impropriamente quando si desidera ereditare campi o implementazioni di metodi. L'ereditarietà tende ad essere applicata correttamente quando si desidera ereditare un'interfaccia, al fine di abilitare il polimorfismo: si ha un sacco di cose diverse che si desidera utilizzare attraverso la stessa interfaccia. Questo accade abbastanza spesso, ma il più delle volte non hai bisogno di polimorfismo, e quindi non hai bisogno di ereditarietà.

    
risposta data 15.04.2018 - 21:15
fonte
1

Se si dispone di un'applicazione console, è possibile strutturare la classe del libro in modo che abbia attributo, copie. Se hai bisogno di una rappresentazione visiva di questi dati, allora un elenco | array di Book potrebbe funzionare?

Non penso che la creazione di BookCopy crei alcun valore verso la riutilizzabilità.

    
risposta data 15.04.2018 - 19:19
fonte
1

Nei termini utilizzati da un bibliotecario, una "copia di un libro" è uno dei possibili libri fisici che hanno lo stesso autore, titolo, ecc.

In termini OO una "copia di un libro" farebbe riferimento a un'istanza della classe Book, dove è possibile che ci siano diverse istanze con lo stesso autore, titolo, ecc.

Se è necessario essere in grado di dire queste istanze con lo stesso autore, titolo, ecc. a parte, puoi aggiungere una proprietà id alla tua classe Book che è unica per ogni istanza.

    
risposta data 15.04.2018 - 19:39
fonte
1

Sembra che tu abbia un libro astratto (con autore, titolo, contenuti ecc.) e un libro fisico (un libro stampato su carta, rilegato in pelle, cartone ecc.)

Avrei un abstractbook di classe, che puoi usare all'interno del catalogo della biblioteca per esempio (perché il catalogo della biblioteca non contiene libri fisici), e una classe PhysicalBook, che conterrebbe un riferimento ad un AbstractBook. Un PhysicalBook (stampato su carta) non è un AbstractBook, quindi non dovrebbe essere una sottoclasse.

Un PhysicalBook avrebbe anche proprietà come il prezzo di acquisto, dove acquistato, lo stato fisico (nuovo di zecca, quasi nuovo, danneggiato, a pezzi), se il libro è in prestito e così via.

Se in realtà scrivi codice per essere utilizzato da una vera e propria biblioteca mondiale, dove le persone prendono seriamente queste cose, potresti anche avere una classe "BookEdition" in cui più edizioni possono avere lo stesso libro astratto, ma diverse date di stampa, ISBN numeri e così via. E una traduzione di un libro potrebbe essere considerata la stessa o un altro libro.

    
risposta data 15.04.2018 - 21:17
fonte
0

Add a copy of a book on a shelf

shelfTop.add(bookOldManAndTheSea);

Move a copy of a book from a shelf to another

shelfTop.remove(bookOldManAndTheSea);
shelfBottom.add(bookOldManAndTheSea);

Questa è una di quelle cose che è molto semplice se la abbatti nel modo giusto.

One solution is create a subclass of Book, i.e. BookCopy.

Eh?

Esattamente quale comportamento ha un BookCopy che Book non ha? Le ristampe sono scontate nella tua biblioteca? Questo non sembra avere molto a che fare con i tuoi problemi di aggiunta / spostamento. Non sono sicuro di dove stai andando con questa linea di pensiero, ma non sembra essere ovunque buona.

    
risposta data 16.04.2018 - 06:13
fonte

Leggi altre domande sui tag