Devo usare Strategy Pattern per questa attività?

1

Sto impostando un validatore di dati che itererà attraverso le righe di un foglio di calcolo e, per ogni colonna, eseguirà un controllo di convalida. Stavo pensando che questo potrebbe essere un compito appropriato per il modello di strategia come segue:

interfaccia IValidator:

public function isValid(rng as range) as boolean
end function

application validator_Number:

'checks whether or not value is a number    
implements IValidator
public function IValidator_isValid(rng as range) as boolean
    IValidator_isValid=isnumeric(rng.value)
end function

application validator_Capitalized:

'checks whether all letters are capitalized in value
implements IValidator
public function IValidator_isValid(rng as range) as boolean
   IValidator_isValid=isnumeric(rng.value) and (ucase(rng.value)=rng.value) 
end function

correttore di verifica:

'iterates through worksheet cells, validating them and 
public sub validationChecker()

dim headerRow as long
dim validator as IValidator

headerRow=1

for row=2 to maxRow
    for column=1 to maxColumn
        'check the column header name and instantiate
        'validator using the appropriate implementation
        select case sheet.cells(headerRow,column).value
            case "NAME"
                set validator=new validator_Capitalized
            case "AGE"
                set validator=new validator_Number
            'etc.
         end select
         if validator.isValid(sheet.cells(row,column)) then
             doSomething()
         endif
     next
next

Ho precedentemente chiesto un'altra domanda sull'utilizzo di Strategy per convalidare i dati Excel e la risposta è stata che non avevo bisogno di farlo perché c'erano solo alcuni tipi di test e quindi le regole potevano essere conservate in un data store. Ma qui ci saranno molti diversi tipi di test di validazione, alcuni dei quali hanno diverse linee di codice. L'implementazione della strategia che ho delineato sopra il modello più appropriato da utilizzare qui?

    
posta sigil 09.02.2015 - 21:24
fonte

1 risposta

4

isValid() potrebbe essere un metodo implementato in un modello di strategia. IMO, il vantaggio del modello è la futura modificabilità. Cioè, ci sarà un futuro bisogno di nuove implementazioni di isValid() e non vuoi cambiare il tuo codice che itera e convalida. Nella definizione di Strategia, questa è la classe Context .

Iltuobloccoselect,checredosarebbenellaclasseContext,nonèflessibilenelmodoincuilohaiproposto,principalmenteperché"conosce" le implementazioni concrete:

    select case sheet.cells(headerRow,column).value
        case "NAME"
            set validator=new validator_Capitalized
        case "AGE"
            set validator=new validator_Number
        'etc.
     end select

Affinché la strategia funzioni come preferisci, probabilmente hai bisogno di una Factory semplice che incapsuli new XXX . Quindi, invece di selezionare / caso, devi solo:

    set validator = Factory.create(sheet.cells(headerRow,column).value)

che chiama efficacemente un metodo create con l'argomento "NAME", "AGE", ecc. che restituirà il validatore appropriato. create() incapsula la logica di selezione / caso.

Il vantaggio di questo è che puoi aggiungere nuovi validatori senza dover modificare il codice in Context . Ovviamente, do devi aggiornare il metodo Factory.create() (essenzialmente il nuovo caso per un nuovo validatore) e scrivere una nuova implementazione IValidator .

Ecco un diagramma aggiornato:

LaclassefactoryeleclassidiimplementazioneseparatesonounsaccodicodiceextracheIMOnon"ripaga" se hai solo due validatori e un singolo Context . Se hai intenzione di aggiungere molti validatori e vuoi davvero la flessibilità di mantenere i dettagli nascosti da Context (che può apparire in più punti), allora fallo!

Se non stai "provando dolore" dalla ripetizione nel mantenimento del codice, probabilmente non hai bisogno di un modello.

    
risposta data 10.02.2015 - 21:10
fonte

Leggi altre domande sui tag