Definizione di molti attributi in una classe

2

Supponiamo che tu debba sviluppare un programma che memorizzi i prodotti con le loro caratteristiche ed esegua alcune operazioni su di loro, e tu decidi di progettare una classe per rappresentare i prodotti. Ogni prodotto ha 10 diverse funzionalità. Tre di loro sono valori numerici. I resti sono valori stringa.

In questo caso, preferisci definire tutti gli attributi di stringa uno per uno in uno sotto un altro formato o un array di stringhe con sette elementi? Qual è più convenzionale e più corretto?

Penso che prendere 10 diversi attributi con il costruttore e assegnarli agli attributi uno per uno sembrino molto negativi. Se utilizziamo un array di stringhe per rappresentare gli attributi, possiamo eseguire un'operazione di assegnazione con un solo ciclo for, che sembra più leggibile.

    
posta Goktug 08.04.2018 - 11:47
fonte

3 risposte

4

Ci sono diverse opzioni qui per affrontare la situazione:

Supponiamo di avere un prodotto con i seguenti attributi:

  • nome
  • Descrizione
  • id
  • color
  • size
  • di peso
  • prezzo
  • categorie
  • brand_id
  • Codice

0) impostandoli tramite gli argomenti del costruttore

Indipendentemente da ciò che si potrebbe dire sul numero di argomenti per un costruttore, qui il caso è chiaro: abbiamo un oggetto dati con i suoi attributi e dobbiamo affrontarlo. Quindi usare 10 argomenti in un costruttore è assolutamente soddisfacente.

1) alcune lingue consentono oltre ai tipici parametri posizionali parametri denominati . Quindi in Python, potresti scrivere Product(name="A shirt", color="red" ...) che si traduce in un costruttore leggibile. E con indentazione non sembra troppo travolgente:

Product(name="A shirt",
        description="A cool shirt",
        id=1,
        color="red",
        size="XXL",
        weight=200,
        price="1000",
        categories=["shirt","clothes", "male"],
        brand_id="0987654321",
        sku="1234567890"
)

2) Uso di Dictionary / Associative array / HashMap

Si prelavella un dizionario con coppie chiave-valore come product["name"]="A shirt" e quando si inizializza l'istanza, si passa il dizionario al costruttore. Quindi è chiaro come viene impostato ciascun attributo. Il problema di ottenere gli argomenti posizionali nell'ordine corretto viene aggirato.

Possibile svantaggio:

Quando al tuo dizionario mancano informazioni importanti, l'errore verrà generato durante il runtime, che potrebbe essere tardivo. Se stai usando un linguaggio tipizzato staticamente, questo tipo di errore potrebbe essere omesso, se hai usato il sistema di tipi invece del costrutto del dizionario debole.

3) utilizzando un'interfaccia fluente insieme a modello di builder

Riceverai qualcosa del tipo:

Product(sku)
   .name("A Name")
   .description("Desc")
   ... 
   .build();

Specialmente, quando non tutti gli attributi sono necessari al momento della creazione, potresti avere gli attributi necessari impostati tramite gli argomenti del costruttore e quelli opzionali tramite interfacce fluenti.

4) A volte è possibile avere gruppi semantici:

Supponiamo che tu stia memorizzando i dati dei clienti, potresti avere una sottoclasse address , che verrebbe incapsulata ( street , zip , city ) o contactinformation ( phone , mail ) che aiutano spezzando il costruttore a parte: Person(firstname, lastname, address, contactinformation) è più leggibile di Person(firstname, lastname, street, zip, city, phone, mail) e a causa di parametri minori, anche se si è vincolati a parametri posizionali più facile ottenere l'ordine giusto.

Ma con attributi di prodotto come sopra, devo ammettere che è difficile trovare un gruppo.

Ai tuoi punti:

In this case, do you prefer to define all string attributes one by one in one under another format or a string array with seven elements ?

Preferisco avere nomi significativi per i parametri. Oltre a ottenere la posizione sbagliata, non sai nemmeno quale posizione nell'array è cosa.

I think taking 10 different attributes with constructor and assigning them into the attributes one by one seem very bad

Non di per sé. Ma se ci sono altre possibilità, potresti volerle usare.

we can perform assign operation with only one for loop, which seems more readable.

Dal punto di vista di "cosa sta succedendo" non si ha troppa ridondanza in corso e il codice risultante potrebbe essere più breve. Concordato. Ma come ho detto, se qualcuno (o forse tu in un anno) ha a che fare con questo codice, si deve investire del tempo per colmare le lacune. E più il tuo codice è ridondante, meno devi compilare, più è facile, lavorare con questo codice.

    
risposta data 09.04.2018 - 09:15
fonte
3

Il numero di assegnazioni o parametri di costruzione non è una metrica ragionevole di quanto sia buona la tua classe.

Il tuo modello di dati dovrebbe essere corretto e utile. Se il tuo modello ha questi dieci attributi, la creazione di una classe con dieci attributi è probabilmente l'approccio giusto.

L'uso di una matrice suggerisce che i valori nella matrice non hanno nomi singoli, ma sono più valori ordinati per l'attributo stesso . Questo potrebbe essere un buon approccio se ci sono molte funzionalità opzionali che un prodotto supporta o non supporta. L'elenco di un nome di funzione nell'array indica quindi che questa funzione è supportata. Tuttavia, questo modello di dati può essere più difficile da usare.

Più dinamico è il tuo modello dati (ad esempio tabelle hash anziché membri oggetto), più diventa fragile e difficile ragionare sulla tua applicazione. All'estremità estrema di questo sono Modelli di valori di entità-attributo che sono completamente dinamici. Sono generalmente inappropriati tranne quando il dominio aziendale non può essere modellato in anticipo.

Ma nel tuo caso, hai un modello con questi dieci attributi limitati, quindi la flessibilità di un modello più dinamico probabilmente non è necessaria e probabilmente controproducente.

    
risposta data 08.04.2018 - 13:04
fonte
1

Quelle 10 caratteristiche diverse, sarebbero le stesse caratteristiche per ogni prodotto? In tal caso, potresti utilizzare una classe di prodotto in più. Potresti avere caratteristiche di base che ogni prodotto ha e caratteristiche speciali che differiscono per prodotto. Ciò richiederebbe un albero ereditario delle funzionalità del prodotto o potresti passare un BasicProductFeatures come primo argomento per il costruttore di ogni prodotto e aggiungere le caratteristiche speciali come argomenti separati.

Soprattutto, pensa logico / modello, smetti di far decidere le tue decisioni di progettazione da cose tecniche. Come "Un sacco di argomenti è male, lasciatemi schiaffarli in un contenitore, ora ho un argomento, evviva". Se il contenitore non significa nulla nel tuo modello, lo hai peggiorato.

    
risposta data 08.04.2018 - 17:17
fonte

Leggi altre domande sui tag