Autore Topic: progettazione classi - android  (Letto 571 volte)

Offline tonno16

  • Utente storico
  • *****
  • Post: 1197
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
progettazione classi - android
« il: 26 Gennaio 2015, 19:32:34 CET »
Salve a tutti. Non so se sia la sezione corretta. Devo affrontare un problema di progettazione.

Nel mio progetto ho una classe MiaClasse con x metodi.
Alcuni oggetti MiaClasse verranno visualizzati in una lista. Altri oggetti MiaClasse verranno sia visualizzati e allo stesso tempo. le operazioni sulla lista che riguardano tale oggetto prevedono operazioni di scrittura lettura su file.

Quindi se seleziono dalla lista MiaClasse a e scelgo eliminia, da sd verrà eliminato un file, o comunque una parte di un file.

Ho pensato a varie soluzioni ma vorrei sapere cosa ne pensate. Quale sia la progettazione migliore.

Pensavo di creare una classe MiaClasseManager che contiene una lista. Tale classe ha metodi per inserire un oggetto MiaClasse, rimuoverlo etc etc etc. Il tutto andrà ad intaccare solo la Lista di oggetti MiaClasse all' interno di MiaClasseManager.

Poi volevo creare MiaClasseManagerDB che estende MiaClasseManager. ma dovrei ridefinire tutti i metodi. in quanto qui il 60% dei metodi deve leggere scrivere su disco.
Oppure MiaClasseManager potrebbe contenere anch' essa una Lista di oggetti MiaClasse, che saranno destinati alla scrittura. Passare un oggetto MiaClasseManager nel costruttore.
Per cui in ogni metodo di quest' ultima richiamo l'oggetto passato .metodo, e implemento anche la scrittura lettura.

Cosi sia ManagerDB che Manager potrebbero implementare la stessa interfaccia.

Cosa dite?

Offline undead

  • Utente senior
  • ****
  • Post: 666
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:progettazione classi - android
« Risposta #1 il: 27 Gennaio 2015, 21:07:10 CET »
Non mi piace.  :D

A parte gli scherzi... il problema è che hai due manager e potresti trovarti con un oggetto sul quale fare operazioni contemporanee (cancelli dalla lista e contestualmente cancelli dal database, per esempio). Ma il concetto stesso di manager si basa sul fatto che quel singolo oggetto gestisce una serie di oggetti. Se lo gestiscono in due allora diventa un casino.

Potresti pensare di delegare queste operazioni sull'oggetto ma l'oggetto non è autosufficiente. Mi spiego: oltre ad accorpare all'interno dell'oggetto funzionalità diverse (gestione lista, gestione db), ti troveresti a portarti in giro copie di una lista o i dati di accesso al db.. e ti troveresti in situazioni imbarazzanti. Esempio: oggetto->delete() può rimuoversi da una lista, può cancellarsi da un db... ma non può cancellarsi da solo.

Mi viene in mente l'uso di "plugin". Tu crei un manager e poi agganci ad esso dei "plugin" derivati da una classe base.
A quel punto hai il plugin del db, il plugin della lista, il plugin del file etc.

Come esempio ti basta pensare all'operazione delete.

Tu chiami delete sul manager, che per prima cosa trova l'oggetto da cancellare, poi chiama la delete di tutti i plugin passandogli l'oggetto e infine cancella l'oggetto.

 :-)

Offline tonno16

  • Utente storico
  • *****
  • Post: 1197
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:progettazione classi - android
« Risposta #2 il: 27 Gennaio 2015, 21:11:23 CET »
Ti ringrazio della risposta. Arrivo da una giornata faticosa. Ho letto velocemente, e domani rileggerò meglio. Nel caso avrò altri dubbi o avrò intuizioni spero di ricevere altrettante risposte. Ti ringrazio intanto

Offline undead

  • Utente senior
  • ****
  • Post: 666
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:progettazione classi - android
« Risposta #3 il: 27 Gennaio 2015, 22:01:52 CET »
Ti ringrazio della risposta. Arrivo da una giornata faticosa. Ho letto velocemente, e domani rileggerò meglio. Nel caso avrò altri dubbi o avrò intuizioni spero di ricevere altrettante risposte. Ti ringrazio intanto
Ti scrivo giusto dello pseudocodice, perché temo non sia comprensibilissimo quello che ho scritto.

Per capirsi al manager aggiungi delle classi derivate da BasePlugIn. Per esempio:

Codice (Java): [Seleziona]
m_Manager.add(new DBPlugIn(sConnectionString));
m_Manager.add(new ListViewPlugIn(myListView));

Questi due oggetti vanno a finire in una lista all'interno del manager

Codice (Java): [Seleziona]
List<BasePlugIn> m_aPlugIns;A questo punto hai ottenuto:
1 solo manager
N plugin che manipolano gli oggetti gestiti dal manager
M oggetti gestiti dal manager

Mettiamo che tu voglia eliminare l'elemento nell'indice 0.

Tu fai una chiamata del tipo:
Codice (Java): [Seleziona]
m_Manager.deleteAt(0);all'interno di deleteAt fai questo (m_aObjects la lista degli oggetti gestiti dal manager e idx l'indice dell'oggetto da cancellare)

Codice (Java): [Seleziona]
myObject tmp = m_aObjects.get(idx);

for(int i = 0; i<m_aPlugIns.size();i++)
m_aPlugIns.get(i).delete(tmp);

m_aObjects.remove(tmp);

 :-)

Offline tonno16

  • Utente storico
  • *****
  • Post: 1197
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:progettazione classi - android
« Risposta #4 il: 28 Gennaio 2015, 19:23:34 CET »
Ho riletto. :)

Allora. In effetti si. Un manager per definizione è qualcosa che aiuta. Quindi inutile averne 2.
Quando parli di delegazione della scrittura agli oggetti intendi dire di implementare l'oggetto MiaClasse con altrettanti metodi per scrivere (Gli stessi ogg MiaClassi si scrivono da soli) su file.
Ma cosi facendo dal mio punto di vista sembra orribile come soluzione. Devo staccare la gestione della scrittura e l'oggetto MiaClasse.

per semplicità ho una sezione dell' app che effettua l' inserimento normale. Poi ho un altra sezione dove viene effettuato l'inserimento normale+relativa scrittura.

Da quello che ho capito il Manager avrà una lista di BasePlugin.

Quello che non ho capito:
-> Cos'è BasePlugIn.
-> Se implemento in manager .add(new DBPlugin(qualcosa));  allora il .add(MiaClass) dove va a finire?
-> DBPlugin estende ListViewPlugin ?

Grazie



Offline undead

  • Utente senior
  • ****
  • Post: 666
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:progettazione classi - android
« Risposta #5 il: 28 Gennaio 2015, 20:14:40 CET »
Quando parli di delegazione della scrittura agli oggetti intendi dire di implementare l'oggetto MiaClasse con altrettanti metodi per scrivere (Gli stessi ogg MiaClassi si scrivono da soli) su file.
Ma cosi facendo dal mio punto di vista sembra orribile come soluzione. Devo staccare la gestione della scrittura e l'oggetto MiaClasse.
Se rileggi l'ho scritto che è una soluzione che si adatta male.  :-P
E' una soluzione interessante quando sei sicuro che hai un solo modo per gestire le cose e quando l'oggetto X deve a sua volta gestire altre operazioni o ha un albero delle classi molto esteso. In questo caso hai ragione, è orribile.

Ma ti faccio un esempio. Tu hai una classe animale, poi una classe mammifero che la estende e poi una classe cane che estende la classe mammifero. Nel tuo manager hai una list di animale. Vuoi caricare da file i cani, i gatti, i mammiferi, etc. Come fai? Ogni classe è diversa e ha parametri diversi. La logica è che tu deleghi alla classe animale/cane/gatto/mammifero il caricamento da file. Questo perché il manager non deve (e non può) conoscere tutte le classi. Questo ti da la libertà di creare la classe pastore tedesco derivata da cane, aggiungerci parametri e caricare e salvare il pastore tedesco senza toccare niente altro se non la classe pastore tedesco.

Ma il tuo caso è opposto: una classe e N modi per salvare/leggere/aggiungere/cancellare. :-)

Citazione
Da quello che ho capito il Manager avrà una lista di BasePlugin.

Quello che non ho capito:
-> Cos'è BasePlugIn.
-> Se implemento in manager .add(new DBPlugin(qualcosa));  allora il .add(MiaClass) dove va a finire?
-> DBPlugin estende ListViewPlugin ?

Grazie
->Baseplugin può essere una classe astratta
->tu implementi addPlugIn e add. add lavora sugli oggetti MiaClass e addPlugIn lavora sui plugin. In generale xxxPlugIn lavora sui plugin e xxx lavora su MiaClass. Quando chiedi di lavorare su MiaClass il manager chiama l'operazione xxx di ogni plugin passandogli quell'oggetto. Ovviamente il plugin può non implementare una funzione (banalmente non fare niente all'interno del metodo o restituire false) o decidere che può operare solo su certi oggetti. Come struttura è abbastanza flessibile.
->DBPlugIn e ListViewPlugIn estendono e implementano BasePlugIn.

 :-)

Offline tonno16

  • Utente storico
  • *****
  • Post: 1197
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:progettazione classi - android
« Risposta #6 il: 29 Gennaio 2015, 18:39:05 CET »
Allora. Ho implementato qualcosa. Ho generato un "UML" usando un editor online. Non sarà tutto a prova di uml 2.0 credo.
Questo è il link. https://drive.google.com/file/d/0B8uy-42yJlGUZjRNYVJDMWhmZk0/view?usp=sharing
Dovrebbe essere visibile a tutti tramite draw (app carina).

In alternativa metto anche una foto.

quindi:
Codice (Java): [Seleziona]
public class MyManager {

    private List<BasePlugin> mBasePlugins;
    private List<MiaClasse> mItems;

    public void addPlugin(BasePlugin basePlugin){
        mBasePlugins.add(basePlugin);
    }

    public void add(MiaClasse e){
        mItems.add(e);
    }

    private void deleteAt(int index){

        MiaClasse e = mItems.get(index);

        for(BasePlugin b : mBasePlugins){
            b.remove(e);
        }

        mItems.remove(index);
    }
}

ovviamente ho un errore. non esiste .remove() su BasePlugin. Avendomi scritto tale pseudo ho le seguenti ipotesi:
- BasePlugin ha anch' esso una sua List<MiaClasse>. BasePlugin implementa .add(MiaClasse) .remove(index); ---->
   cosi non ho errori. Però a sto punto .add() di Manager deve con un for chiamare .add() di ogni Plugin della lista.
 Cosi facendo se nella lista ho 4 elementi e ho 10 plugin mi ritrovo con 40 elementi in memoria.

Avendo fatto tale considerazione ho anche ipotizzato una seconda ipotesi.
- Il .remove() messo da te potrebbe essere il mio moreForThis() ???  --> cosi facendo BasePlugin non ha nessuna lista. Tale oggetto esiste per fare qualche lavoraccio dandogli in input una istanza di MiaClasse. Come può essere la scrittura su file o l'upload su web.

Anche quest' ultima dovrebbe filare, e con una lista di 4 elementi ho solo 4 elementi in memoria, che risiedono appunto in List<MiaClasse> dell' oggetto Manager.

Grazie

Offline undead

  • Utente senior
  • ****
  • Post: 666
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:progettazione classi - android
« Risposta #7 il: 29 Gennaio 2015, 18:45:39 CET »
Avendo fatto tale considerazione ho anche ipotizzato una seconda ipotesi.
- Il .remove() messo da te potrebbe essere il mio moreForThis() ???  --> cosi facendo BasePlugin non ha nessuna lista. Tale oggetto esiste per fare qualche lavoraccio dandogli in input una istanza di MiaClasse. Come può essere la scrittura su file o l'upload su web.
Esatto. BasePlugIn non ha una lista. Tu passi ai metodi dei plugin una istanza di MiaClasse poi loro fanno solo scrittura/cancellazione/etc. Servono prorpio a disaccoppiare la lista di oggetti MiaClasse dalle singole operazioni sugli oggetti.

 :-)

Offline tonno16

  • Utente storico
  • *****
  • Post: 1197
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:progettazione classi - android
« Risposta #8 il: 29 Gennaio 2015, 18:59:11 CET »
Ok. Allora ce l' abbiamo fatta. Grazie veramente.

Però ora la domanda è quasi di dovere......Che differenza c'è  tra questa soluzione e una soluzione dove BasePlugin implementa .uploadOnServer(url), .writeOnFile(path) , otherSpeciality(field).
Diciamo che nel mio caso ho cosi pochè problematiche che questa ultima soluzione sarebbe adottabile mentre in un progetto di dimensioni più grandi un BasePlugin ha sicuramente qualcosa in più.

Inoltre, Il mio Manager viene istanziato all' avvio dell' applicazione. Viene "eliminato" quando termina l'app, che sia l'utente o android a farlo. In più sezioni richiedo getListItem() che rtitorna List<MiaClasse>.
E' fattibile implementare Manager con singleton ? Cosi da evitare anche letture inutili da disco? Inoltre se in una sezione (Fragment) chiamo .add(miaClasse) per aggiungere istante temporanee alla lista, in una diversa schermata se Manager verrà istanziato nuovamente è chiaro che gli item aggiunti non ci saranno nella lista, ma saranno presenti solo quelli presenti su disco.

Offline undead

  • Utente senior
  • ****
  • Post: 666
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:progettazione classi - android
« Risposta #9 il: 29 Gennaio 2015, 19:35:16 CET »
Però ora la domanda è quasi di dovere......Che differenza c'è  tra questa soluzione e una soluzione dove BasePlugin implementa .uploadOnServer(url), .writeOnFile(path) , otherSpeciality(field).
Diciamo che nel mio caso ho cosi pochè problematiche che questa ultima soluzione sarebbe adottabile mentre in un progetto di dimensioni più grandi un BasePlugin ha sicuramente qualcosa in più.
Accorpare tutto in baseplugin ha poco senso secondo me. Baseplugin diventa una mega-classe che fa 10 cose diverse... scrive/legge files, scrive/legge da database.. e magari un domani pure online. A quel punto se devi accorpare tutto in una classe puoi mettere tutte le funzioni nel manager e sei a "posto".

Più che vantaggio intrinseco del baseplugin il problema è il tipo di codice ti ritrovi per le mani se scegli l'altra strada.
Una mega-classe che gestisce oggetti X che usa il filesystem, il database, le liste, etc... non è riusabile. E' un blocco di codice monolitico che ti richiede tanto lavoro per cambiare poche cose o riadattarlo ad un altro progetto. Hai scritto qualcosa che "funziona" ed è morta lì.

Per principio non sono contrario al codice scritto "male", tutti sappiamo che poi nella pratica il codice tende a sporcarsi.
Se però parliamo di design allora secondo me è giusto cercare di fare le cose per bene.

Per sporcare il codice c'è sempre tempo...  :-)

Citazione
Inoltre, Il mio Manager viene istanziato all' avvio dell' applicazione. Viene "eliminato" quando termina l'app, che sia l'utente o android a farlo. In più sezioni richiedo getListItem() che rtitorna List<MiaClasse>.
E' fattibile implementare Manager con singleton ? Cosi da evitare anche letture inutili da disco? Inoltre se in una sezione (Fragment) chiamo .add(miaClasse) per aggiungere istante temporanee alla lista, in una diversa schermata se Manager verrà istanziato nuovamente è chiaro che gli item aggiunti non ci saranno nella lista, ma saranno presenti solo quelli presenti su disco.
Io non ho niente contro i singleton. Qualcuno li odia ma secondo me puoi benissimo creare il manager nell'application invece che nell'activity e poi accederci dai fragment. In quel modo hai una sola istanza "globale" del manager senza nemmeno bisogno di dichiararla static.

In tanti si lamentano del singleton, non sarà la pratica più elegante o strutturata ma alla fine parliamo pur sempre di un manager che per sua definizione deve gestire degli oggetti. Avere 5 istanze dello stesso manager.. boh.. secondo me serve a solo a creare confusione.   :-)

Offline tonno16

  • Utente storico
  • *****
  • Post: 1197
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:progettazione classi - android
« Risposta #10 il: 29 Gennaio 2015, 20:05:08 CET »
Si, infatti voglio codice il più pulito e riusabile possibile. Cambierò anche MiaClasse con generici se riesco a fare qualcosa

Post unito: 29 Gennaio 2015, 20:07:38 CET
Avevo trovato un bellissimo articolo di un tipo che spiegava (secondo lui) il perchè non usare Application e il pattern singleton. Aveva pure ipotizzato uno scenaio con classi e quant' altro. Ora non lo trovo.

Grazie.
« Ultima modifica: 29 Gennaio 2015, 20:07:38 CET da tonno16, Reason: Merged DoublePost »