Come progettare un modello di classe per prodotti specifici, alcuni dei quali possono contenere gruppi di modelli di prodotto specifici

1

Domanda sulla progettazione della classe

Sto cercando di trovare un buon modo per progettare il mio sistema di classe.

Ho una classe Product per calcolare varie specifiche del prodotto. Ho due gruppi di modelli di prodotto, ciascuno contenente diversi numeri di modello: {10, 20, 30} e {50, 60, 70}. Condividono alcune caratteristiche simili (vale a dire il modo in cui viene calcolato il peso) ma hanno calcoli aggiuntivi del prodotto diversi (ad esempio alcune funzionalità dipendono dalla lunghezza del prodotto e altre no, a seconda del gruppo di modelli)

Il modello di classe che ho attualmente è Product principale per tutti i modelli (in realtà originariamente solo per 50, 60, 70) e un modello specifico Product10 è stato aggiunto in seguito e funziona solo per il modello 10. Ora, una nuova aggiunta ha introdotto i modelli 20 e 30, che sono simili al modello 10. Invece di aggiungerli come classi separate, quasi identiche a 10, ho pensato che fosse il momento di riprogettare.

problema

Nella mia attuale implementazione, la classe Product10 è alimentata dalla principale Product class (responsabile per "la maggior parte dei modelli") e Product10 è la più strana. Forse va bene, ma ora sto ottenendo più numeri di modello simili a Product10 e sto cercando un modo migliore per strutturare il mio codice.

Attualmente vedo che ci sono diversi modi per progettarlo.

  • crea una classe per ogni modello (potrebbe essere uno spreco)
  • crea una "classe di Dio" che contiene il codice per tutti i modelli (la classe può essere gonfia)
  • crea sottogruppi per i modelli, ovvero una classe che copre un insieme di modelli come {10, 20, 30} o {50, 60, 70}
  • qualcos'altro.

Quello che cerco

Cerco un buon modo di utilizzare il design OO per la mia situazione specifica ... Ovvero,

  • Penso che sia una buona idea avere una classe generica di qualche tipo
  • Non sono sicuro se dovrei creare una classe per rappresentare "un insieme di modelli simili" o se trattare i modelli separatamente

Il mio obiettivo è creare una classe appropriata in base al numero di modello.

Quale potrebbe essere una buona decomposizione di classe?

    
posta Dennis 06.11.2015 - 20:32
fonte

4 risposte

2

Se tutte le tue classi condividono la stessa logica, crea una classe base che contenga i metodi. Tutta la logica che è simile in tutti i prodotti va in questa classe base. Per ogni gruppo di progetti con logica simile per determinati metodi (ad esempio, il calcolo di una funzionalità uguale per tutti i modelli), creare una sottoclasse che implementa questa logica.

Naturalmente, questo funziona solo se il calcolo delle caratteristiche non è strutturato in modo tale da dover essere duplicato "across". Ad esempio, è possibile avere due caratteristiche "Beta" e "Gamma" che devono essere calcolate per tre tipi di modelli A, B e C. Se A e B condividono alcune logiche di calcolo per "Beta", è possibile creare una classe base per A e B che implementano questa logica. Tuttavia, se il calcolo per la funzione "Gamma" è lo stesso per A e C ma non B, questo non funzionerà.

In tal caso, ti consiglio di utilizzare il modello di strategia. Implementare calcoli di funzionalità in classi di calcolatori separate e semplicemente comporre i modelli di prodotto chiamando le giuste classi di calcolo. Tutti i modelli dovrebbero quindi semplicemente estendere la singola classe di base che definisce tutti i calcoli di "funzionalità" in modo che il contratto tra gli oggetti del dominio sia lo stesso.

    
risposta data 07.11.2015 - 12:59
fonte
0

Pensieri casuali

The class model I currently have is main Product for all models (actually originally for 50, 60, 70 only) ... but have different product add-on computations

Per prima cosa progettare il caso base. Da lì analizzare attentamente per identificare le differenze precise con le entità una tantum. Non essere così presuntivo da distruggere le cose a livello di classe.

Ora pensa a come astrarre concettualmente cosa sta succedendo in modo da vedere cose che "sono uguali, ma differenti". Questo è distinto da cose che sono solo diverse.

have different product add-on computations (i.e. some features depend on product length and some do not, depending on the model group)

Modello modello?

Questo potrebbe essere un metodo virtual in una classe base. Soprattutto se c'è un processo di base e questo metodo è un'implementazione diversa dello stesso passo.

class Product10 is feeding off the main Product class (responsible for "most models") and Product10 is being the odd one out.

static le cose sono un ottimo modo per mantenere la funzionalità in una classe base senza far parte della implzione dell'istanza; senza ereditarlo dove non è necessario.

Pensa costantemente al principio della singola responsabilità. Anche al punto della possibilità di dare funzionalità a classi esistenti - anche classi di framework - tramite extension methods.

create a "god class" that contains code for all models (class may be bloated)

Modello visitatore?

Codici / classi specializzati indirizzati alle variazioni di Product . Questo è il codice "do stuff", forse addirittura "inserisce" un template (pattern) in una classe base.

I principi OO sono frattali.

  • I principi si applicano in classe, metodo, struttura di controllo del flusso, ecc.
  • Non abbandonare la progettazione di classi utili solo perché:

    • Sarebbe "troppo piccolo"
    • Sono 2 (3, 4, ...) livelli profondi nella mia ereditarietà o struttura composita.
    • È facile scrivere il codice adesso, proprio qui.
  • Anche le classi sono strutture di dati.

    • Trovo che quando progetto in pezzi discreti e focalizzati l'atto di progettare è indulgente.
    • Avevo una classe con 3 proprietà: giorni, mesi, anni. Solo 1 metodo: aggiunta di questa STRUTTURA agli oggetti DateTime.
  • Parametri del metodo IS dependency injection

  • metodi delegati è composizione
risposta data 13.11.2015 - 00:23
fonte
0

Se le classi dell'insieme {10, 20, 30} hanno lo stesso comportamento, crea solo 1 classe che deriva da Product . Lo stesso per {50, 60, 70}.

abstract class Product {
    public function getWeight() {
        //Some computation
    }

    abstract public function getVolume();
}

class Product102030 extends Product {
    public function getVolume() {
        //Compute volume based on something
    }
}

class Product506070 extends Product {
    public function getVolume() {
        //Compute volume based on something else
    }
}

My goal is to create an appropriate class based on model number.

Se ho capito bene, vuoi anche una classe in grado di instanciare il% co_de corretto sulla base di un numero di modello. Questo in genere potrebbe essere fatto in una fabbrica.

class ProductFactory {
    public static function create($number) {
        switch($number) {
            case 10:
            case 20:
            case 30:
                return new Product102030;
            case 50:
            case 60:
            case 70:
                return new Product506070;
            default:
                throw new Exception ('Unsupported model number !');
        }
    }
}

Un utilizzo tipico potrebbe essere:

$p1 = ProductFactory::create(10); //$p1 is a Product102030 instance
$p2 = ProductFactory::create(60); //$p2 is a Product506070 instance
    
risposta data 13.11.2015 - 14:17
fonte
0

I think it is a good idea to have a generic class of some sort I am not sure whether I should create a class for to represent "a set of similar models" or whether to treat models separately My goal is to create an appropriate class based on model number. What could be a good class decomposition?

Risposta rapida breve

"La classe di Dio" è una buona idea, che è già usata da altri. A volte, si applica "Una classe per rappresentare un insieme di modelli simili", a volte si applica "numero di modello".

Risposta lunga e noiosa

Contrariamente a quanto fanno molte persone, un modo per progettare una gerarchia di clas, non deve avere alcuna gerarchia e iniziare con diverse classi indipendenti.

Verifica quali caratteristiche condividono le classi, come proprietà, quali operazioni eseguono e come vengono eseguite le operazioni.

Un'altra cosa da considerare è che alcuni valori, che sono condivisi da più classi, forse calcolato, e altri no.

Questo è un modo per rilevare i campi dalle proprietà.

La Figura 1 mostra un U.M.L. diagramma di classe, con 3 classi non correlate.

..............................
..+------------------------+..
..|  None: Model10Class    |..
..+------------------------+..
..| [+] string: ModelName; |..
..| [+] float:  Weight;    |..
..| [+] FSize:  Size;      |..
..| [+] ColorType: Color;  |..
..| [+] ...                |..
..+------------------------+..
..| [+] void:   Function1; |..
..| [+] ...                |..
..+------------------------+..
..............................
..+------------------------+..
..|  None: Model20Class    |..
..+------------------------+..
..| [+] string: ModelName; |..
..| [+] float:  Weight;    |..
..| [+] FSize:  Size;      |..
..| [+] ColorType: Color;  |..
..| [+] ...                |..
..+------------------------+..
..| [+] void:   Function1; |..
..| [+] void:   Function2; |..
..| [+] ...                |..
..+------------------------+..
..............................
..+------------------------+..
..|  None: Model30Class    |..
..+------------------------+..
..| [+] string: ModelName; |..
..| [+] float:  Weight;    |..
..| [+] FSize:  Size;      |..
..| [+] ColorType: Color;  |..
..| [+] ...                |..
..+------------------------+..
..| [+] void:   Function1; |..
..| [+] void:   Function2; |..
..| [+] void:   Function3; |..
..| [+] ...                |..
..+------------------------+..
..............................

Poiché "ModelName", "Weight", "Size", e "Function1" sono condivisi da tutte le classi, lascia generare una nuova classe base con quei membri, e, sottoclassi le classi precedenti da esso.

Il "..." significa forse che ci sono o meno altri membri, condiviso o meno da altre classi.

La Figura 2 mostra un U.M.L. diagramma di classe, dove è stata estratta una classe base dalle 3 classi.

..+------------------------+..
..|   None: ProductClass   |..
..+------------------------+..
..| [+] string: ModelName; |..
..| [+] float:  Weight;    |..
..| [+] FSize:  Size;      |..
..| [+] ColorType: Color;  |..
..+------------------------+..
..| [+] void:   Function1; |..
..+------------------------+..
..............................
..+------------------------+..
..|  None: Model10Class    |..
..+------------------------+..
..| [+] ...                |..
..+------------------------+..
..| [+] ...                |..
..+------------------------+..
..............................
..+------------------------+..
..|  None: Model20Class    |..
..+------------------------+..
..| [+] ...                |..
..+------------------------+..
..| [+] ...                |..
..| [+] void:   Function2; |..
..+------------------------+..
..................................
..+----------------------------+..
..| Model20Class: Model30Class |..
..+----------------------------+..
..| [+] ...                    |..
..+----------------------------+..
..| [+] ...                    |..
..| [+] void:   Function3;     |..
..+----------------------------+..
..................................

Nota che "Model30" ha anche gli stessi membri di "Model20".

[in costruzione]

...

    
risposta data 14.11.2015 - 00:59
fonte