Pagina 1 di 4 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 38
  1. #1

    [OOP] Come si struttura un buon progetto?

    Salve in occasione della manutenzione della mia applicazione (un gioc) ho deciso di fare le cose per bene questa volta cercando di rispettare tutte le regole di buona programmazione. Ora dopo essermi letto una marea di guide sulla programmazione ad oggetti, mi è sorto un dubbio, ovvero come devo dividere il mio progetto perchè rispetti tutte le regole ? vado subito al concreto con un'esempio:

    Codice PHP:
    class Utente{
        public function 
    __construct($id)
        
    //Funzioni Per manipolare la tabella Utente
        
    public function getSoldi();
        public function 
    setSoldi($soldi);
        
    //ecc.
    }
    abstract class 
    Item{
        public function 
    __construct();
    }

    class 
    Arma extends Item{
        public function 
    __construct($user); //Ipotesi 1 passo l'oggetto utente
        
    public function getListaWeapon(); //Resituisce un array con le armi comprabili dall'utente
        
    public function buyWeapon($id_arma); //Compra un'arma
        
    public function getEquipedWeapon();//Restituisce l'arma equipaggiata dell'utente
        
    public function hasBoughtWeapon($id_arma); //Restituisce true se l'utente ha comprato già l'arma
        
    private function canBuyWeapon($id_arma); //restituisce true se può comprare l'arma
       //ecc.
    }

    class 
    Armatura extends Item {
        
    //Come arma

    Ora il dubbio in concreto è chi si deve occupare del comprare l'arma/armatura ad esempio ? La classe utente o classe Arma ? In teoria le due cose dovrebbero essere staccate ovvero la classe utente dovrebbe occuparsi dell'utente (e magari di comprare l'oggetto) e la classe Arma di manipolare l'oggetto arma...ma come interegaiscono tra di loro le due classi in concreto? Passare per riferimento l'oggetto arma (magari inizializzato con l'id dell'arma da comprare) non mi sembra un buon modo di farle interagire in quanto rende dipendenti le due classi l'una dall'altra e a sto punto oltre tutto non solo Arma diventerebbe quasi inutile (in quanto terrebbe giusto una funzione che restituisce i dati dell'arma) ma poichè alla fine l'applicazione è basata solo sulle iterazioni che l'utente compie se applicassi il prinipio di sopra mi ritroverei ad avere solo funzioni nella classe Utente a questo punto.

    Grazie in anticipo e scusate la lunghezza

  2. #2
    Ciao! La mia non è una risposta definitiva, ma solo uno spunto per un eventuale dibattito
    Hai mai valutato di creare uno "strato superiore" che fa tutte le operazioni? Mi spiego: una serie di funzioni (classi sarebbe forse eccessivo, nella mia filosofia) che allacciano arma a utente, verificano le possibilità, fanno transazioni eccetera... Discutiamone perchè anch'io sono interessato!

  3. #3
    Itendi una classe Utente_Item (che gesisce solo le operazione tra queste due classi) oppure una più generica GameCore() (che quindi gestisce magari tutte le iterazioni fra le classi)?

  4. #4
    Allora,

    leggere manuali a gogo non basta.. dovresti studiarti un testo universitario (o meglio, piu testi) per fare una buona oop, di certo non i manualetti o simili... ci sono anche ebook sui Design Pattern che in genere sono molto utilizzati in OOP.. cmq vediamo di capire quello che intendevi con le classi nell'esempio...

    la classe Utente:

    la classe utente, o meglio direi Character visto che usa armi per sparare, deve avere le funzioni per maneggiare le armi e gli oggetti... quindi metodi del tipo "spara", "raccogli arma", "cambia arma" e quant'altro. A seconda del tipo di gioco, potrebbe essere compito della classe Utente sapere se è in grado o meno di usare un'arma, non viceversa. Nel senso che l'arma non sa chi può gestirla.. è un pò come chiedere ad un fucile se può essere maneggiato da un bambino o da una donna...

    Quindi o è utente che sa se può usare o meno un'arma, oppure ci vorrebbe un'altra classe, magari estesa da utente... una classe tipo "Razza" che impedisca alòl'utente di usare certe armi.. ad esempio se è un fantasy, puoi dire che gli elfi non possono usare le scuri e che i nani non possano usare i bastoni da mago... oppure sbizzarrisciti dipende un pò dalle regole del gioco.

    Ancora:

    codice:
     public function getListaWeapon(); //Resituisce un array con le armi comprabili dall'utente 
        public function buyWeapon($id_arma); //Compra un'arma 
        public function getEquipedWeapon();//Restituisce l'arma equipaggiata dell'utente 
        public function hasBoughtWeapon($id_arma); //Restituisce true se l'utente ha comprato già l'arma 
        private function canBuyWeapon($id_arma);
    tutti questi metodi non possono essere dati ad arma, ma a qualcos'altro.. ad esempio ad Utente.. è utente che ha la lista delle armi nel suo zaino, che può comprare un'arma (non si è mai visto che un fucile compri una pistola), che consoce quello che ha comprato, che sa se può o non può comprare un'arma. Arma al piu ha come metodi:

    + spara
    + ricarica
    + quante munizioni restano

    e simili.

    Ancora:

    Arma può implementare Item, ma nella sua accezione base.. nel senso che arma è un oggetto.. Item può avere metodi del tipo "quanto peso", "quanto ingombro", "di che materiale sono fatto" che Arma poi implementerà a suo piacimento.. Nella maniera piu assoluta Item può contenere metodi riferiti a qualcosa che spara, così la classe Item puoi usarla come base anche per oggetti che non sparano, esempio libri, fogli, mappe etc etc

    Insomma, per riassumere: ogni oggetto deve compiere azioni o avere proprietà specifiche per il tipo di oggetto, metodi ibridi (tipo arma che può comnprare qualcosa) sono sinonimi di errori concettuali. Devi anche basarti sul tuo buonsenso e la tua esperienza per capire chi è che compie un'azione e chi la subisce, chi è che ha delle capacità e chi no e quant'altro e tramutare il tutto in classi. Ti suggerisco di crearti degli schemi prima, non passare subito al codice.. schemi Uml per la precisione, con cui tirare giù lo schema concettuale delle tue classi e poi passare all'implementazione (ci sono tutta una serie di programmi free e non che ti aiutano a farli, credo eclipse stesso abbia i moduli per fare progetti su uml)


    ps: E' abbastanza inutile dare all'arma il riferimento all'utente. Non ne vedo l'utilizzo

    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  5. #5
    Innanzi tutto grazie per la speigazione Santino...i pattern li ho un pò visti e capito a che servono in linee generali. Detto questo ti rignrazio per tutta la spiegazione, quello che hai detto però era abbastanza chiaro come ho detto io all'inizio

    In teoria le due cose dovrebbero essere staccate ovvero la classe utente dovrebbe occuparsi dell'utente (e magari di comprare l'oggetto) e la classe Arma di manipolare l'oggetto arma...
    Il problema di fondo è che dal momento che io di tutte quelle funzioni che hai citato tu non ne faccio uso nel gioco, ma utilizzo solo funzioni che fanno interagire l'utente con arma, come scritto nel codice nell'esempio della prima pagina, dove/come devo implementare le funzioni di interazione ? Perchè se io facessi come fai tu mi ritroverei una sola classe Utente di 10k righe di codice e mini classi che restituiscono semplicemente un una riga del DB (info sull'arma ad esempio). Ora anche grazie a tobler mi è venuta in mente una possibile soluzione:

    Codice PHP:
    //I metodi delle classi rimangono sempre gli stessi del primo messaggio
    class Utente{}
    abstract class 
    ManageItem extends Utente{}
    class 
    ManageArma extends Item {}
    class 
    ManageArmatura extends Item {} 
    Che ne pensate ? Aggiungo un nuovo problema però...come dovrei gestire la classe Combat o Gilda o Messaggi ? In tutti questi casi caso l'utente A (padre) deve interagire con l'utente B. Ecco un'esempio:

    Codice PHP:

    class Fight extends Utente{
        public function 
    fight_individual($id);
        public function 
    fight_clan($id);
        public function 
    can_attack($id);
       
    //ecc.
    }

    class 
    Clan extends Utente {
        public function 
    add_friend($id);
        public function 
    remove_friend($id);
        
    //ecc.
    }
     
    class 
    Messaggi extends Utente {
        public function 
    sandMSG($id);
        public function 
    deleteMSG($id);
        
    //ecc.   

    In questo caso però avrei necessita di gestire due istanze user padre...

  6. #6
    Utente di HTML.it L'avatar di dottwatson
    Registrato dal
    Feb 2007
    Messaggi
    3,012
    Credo che invece il discorso va girato in un' altro modo:

    Prima del codice va sempre pensato il database.. è da quello che ti guida nella creazione delle classi....

    Codice PHP:
    $bag->open and_search("select * from bag where object ='pietra' and attribute='green' and user_id=33 ");


    if(empty(
    $bag)){
    ...

    e zak!
    i metodi e le classi nascono da se
    Non sempre essere l'ultimo è un male... almeno non devi guardarti le spalle

    il mio profilo su PHPClasses e il mio blog laboweb

  7. #7
    Onestamente non capisco come possa cambiare qualcosa la struttura del DB in questo caso...Al massimo quello che vedo è una similitiduine di problema che in un caso viene risolta con una tabella che contiene user_id e item_id e quantitià (la tua bag) e in un'altra non trova una soluzione in quanto le logiche di iterazione devono essere il più possibile divise, si in effetti questo topic dovevo chiamarlo "Come gestire le operazioni 1,n (caso messaggi,combat) e 1,1 (utente -> item) in OOP" (1,1 perchè un'utente in questo caso non può manipolare due armi in contemporanea)

  8. #8
    Utente di HTML.it L'avatar di dottwatson
    Registrato dal
    Feb 2007
    Messaggi
    3,012
    cambia eccome!

    il tipo di struttura del database è fondamentale per poter gestire il codice che scriverai! se il database ha una struttura ben fatta, elastica ed espandibile, allora dovrai fare delle classi elastiche chiare ed espandibili, e adottera la stessa filosifia del databae.

    successivamente sapendo come devi interagire con lui scegli se usare le abstract, le estensioni e quant' altro.

    la base dati è... la base
    Non sempre essere l'ultimo è un male... almeno non devi guardarti le spalle

    il mio profilo su PHPClasses e il mio blog laboweb

  9. #9
    mmm e allora dato la tabella utente, armi, e utente_armi (che contiene id utente,id arma,quantità) come impostaresti le classi ?

    Codice PHP:
    //Ipotesti 1 estendi la classe user
    class Utente{}
    //Comprare,vendere,equipaggiare, viene gestito dalle classi sottostanti
    abstract class ManageItem extends Utente{}
    class 
    ManageArma extends Item {}
    class 
    ManageArmatura extends Item {}

    //Ipotesi 2 crei una classe item indipendente
    class Utente{}
    //Comprare,vendere,equipaggiare, viene gestito dalle classi sottostanti
    abstract class Item{}
    class 
    Arma extends Item {}
    class 
    Armatura extends Item {}

    //Ipotesi 3 crei una classe di intermezzo (un pò come è stato fatto nel DB)
    Class Utente{} //Gestisce solo l'utente
    Class Utente_arma{} //Compra.vende,equipaggia,ecc.
    //Queste classi ritornano solo le informazioni sull'arma
    abstract class Item{}
    class 
    Arma extends Item {}
    class 
    Armatura extends Item {} 
    Quale di queste ipotesi scegleresti tu ? E nel caso della classe combat/messaggi/clan in cui è necessaria l'iterazione di due oggetti utenti ?

  10. #10
    Utente di HTML.it L'avatar di dottwatson
    Registrato dal
    Feb 2007
    Messaggi
    3,012
    adotterei una struttura piu semplice, è sempre un problema risalire tutte le gerarchie di estensione e implementazione
    Codice PHP:
    class arma{
        ....
        ....
        }

    class 
    utente{
        private 
    $armi null;
        .....
        .....
        ....
        

        
        final public function 
    controlla_armi(){
            
    //interrogo il db e verifico le armi a mia disposizione, collezionandole in $this->armi 
            //riutilizzabile per rinnovare il parco armi a seguito di una nuova arma acquisita
            
    return $this;
            }
        
        final public function 
    ha_arma($name){
            
    $out=0;
            if(
    4this->$armi != null){
                foreach(
    $this->armi as $arma){
                    if (
    $arma->name == $name){
                        
    $out++;
                        }
                    }
                } 
            return 
    $out
            }
        } 
    la classe item ti può venire in aiuto se hai dei modelli abbastanza flessibili da poterli adottare in tutte le sitiuazioni a mio parere
    Non sempre essere l'ultimo è un male... almeno non devi guardarti le spalle

    il mio profilo su PHPClasses e il mio blog laboweb

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.