Parametrizzazione vs sottoclasse

1

Esempio tratto da: Sviluppo software agile: principi, modelli e pratiche

Un nuovo dipendente viene aggiunto dal ricevimento di una transazione AddEmp. Questa transazione contiene il dipendente nome, indirizzo e numero di impiegato assegnato. La transazione ha tre forme:

AddEmp <EmpID> "<name>" "<address>" H <hourly-rate>
AddEmp <EmpID> "<name>" "<address>" S <monthly-salary>
AddEmp <EmpID> "<name>" "<address>" C <monthly-salary> <commission-rate>

proposta classe di impiegati Aggiungitransazionedipendente

Lamiadomandasarebbe"migliore" se invece di sottoclasse di AddEmployeeTransaction avessimo una fabbrica per la classificazione salariale e il piano retributivo?

Se meglio è un termine troppo vago, quali sono gli svantaggi del mio design rispetto a quello proposto dallo zio Bob?

Diciamo dentro EmployeeTransaction abbiamo SalaryClassificationFactory e chiamiamo SalaryClassificationFactory.get(SalaryDetails d)

dove,

enum SalaryId{H,S,C};


struct hourly
{
    int hourlyRate;
};

struct monthly
{
    int monthlySalary;
};

struct commissioned
{
    int salary;
    int commisssionRate;
};
struct SalaryDetails
{
    SalaryId kind;
    union SalaryUnion
    {
        hourly h;
        monthly s;
       commissioned c;
    }
};
    
posta q126y 15.01.2016 - 05:12
fonte

2 risposte

1

Una delle decisioni progettuali che Zio Bob ha realizzato durante la creazione del suo design è che Classificazione dei pagamenti dovrebbe essere Apri per estensione . Ciò significa che l'aggiunta di nuove classificazioni di pagamento non dovrebbe richiedere la modifica o la ricompilazione del codice esistente. Il tuo design rompe questa decisione di progettazione, perché per aggiungere una nuova classificazione di pagamento, devi aggiungere nuovo valore a SalaryId enum, nuova struttura e aggiungerlo a SalaryUnion , forzando la ricompilazione di tutto il codice che dipende da SalaryId e SalaryDetails .

Ma questa è la decisione dello zio Bob. Se tu stesso decidi che non vuoi accettare la complessità creata rendendo Open Design for Extension, puoi andare con il tuo design.

    
risposta data 15.01.2016 - 09:27
fonte
2

Tipici schemi di fabbrica posticipano la creazione di alcuni oggetti a qualche fabbrica, consentendo alla fabbrica di scegliere il tipo o l'oggetto finale, ma lo fanno da un'interfaccia comune, condivisa (solitamente semplice, spesso astratta) che richiede un oggetto . Ad esempio, (dal link )

Product ProductFactory.createProduct(ProductId id)

Qui la fabbrica può creare la sottoclasse appropriata di Product consultando ProductId e presumibilmente un catalogo prodotti. Tutti i diversi tipi che la fabbrica può creare sono richiesti usando lo stesso metodo.

Mi sembra che i parametri necessari per realizzare ciascuna delle tre transazioni di classificazione degli stipendi siano sostanzialmente diversi l'uno dall'altro. Pertanto, un pattern di metodo factory tradizionale probabilmente non si applica a tutti e tre.

Potresti nascondere l'implementazione basata sulla sottoclasse esistente dietro un'altra classe, ma avresti ancora bisogno di tre metodi, ognuno con parametri diversi, e di conseguenza, la classe che nasconde non sarebbe, a mio parere, una fabbrica.

A meno che tu non possa unire le varie descrizioni della classificazione salariale sotto un tipo comune, dì come in:

AddEmployeeTransaction 
    AddEmployeeFactory.createAddEmployee ( EmployeeCompensationClassification ecc, 
                                           EmployeeInfo who )

Ora questo metodo sembra uno schema di fabbrica, ma non abbiamo ottenuto nulla perché tutto ciò che abbiamo fatto è rinviare lo stesso tipo di problema alla creazione di EmployeeCompensationClassification .

Se potessi ridurre tutte le classificazioni di retribuzione retributiva a quelle di un codice semplice (ad esempio un nome di classificazione, o un numero identificativo di classificazione), penso che uno schema di fabbrica avrebbe dei meriti.

    
risposta data 15.01.2016 - 06:15
fonte

Leggi altre domande sui tag