2013-08-01 20 views
15

È possibile avere parametri con nome con valori predefiniti in groovy? Il mio piano è di creare una sorta di fabbrica di oggetti, che può essere chiamata senza argomenti per ottenere un oggetto con valori predefiniti. Inoltre, avrei bisogno della funzionalità per impostare in modo esplicito qualsiasi parametro per l'oggetto. Credo che questo sia possibile con gli argomenti delle parole chiave Python, per esempio.parametri denominati con valori predefiniti in groove

Il codice che sto tentando con questo momento è qualcosa di simile al di sotto

// Factory method 
def createFoo(name='John Doe', age=51, address='High Street 11') { 
    return new Foo(name, age, address) 
} 

// Calls 
Foo foo1 = createFoo() // Create Foo with default values 
Foo foo2 = createFoo(age:21) // Create Foo where age param differs from defaut 
Foo foo3 = createFoo(name:'Jane', address:'Low Street 11') // You get the picture 
// + any other combination available 

La vera applicazione che sto lavorando su avrà molto di più di parametri, e quindi molto più combinazioni necessario.

Grazie

UPDATE:

Il metodo factory sto pensando è a scopo di test. Non posso davvero toccare la vera classe Foo e specialmente non i suoi valori di default.

@dmahapatro e @codelarks rispondono di seguito hanno avuto un buon punto nell'utilizzo di una mappa come un parametro che mi ha dato un'idea di una possibile soluzione. Potrei creare una mappa con i valori predefiniti desiderati e sovrascrivere i valori necessari, e passarla al metodo factory. Questo probabilmente farà il lavoro e ci andrò, a meno che non abbia un accenno ad un approccio migliore.

Il mio approccio corrente al di sotto

defaults = [ name:'john', age:61, address:'High Street'] 

@ToString(includeFields = true, includeNames = true) 
class Foo { 
    // Can't touch this :) 
    def name = '' 
    def age = 0 
    def address = '' 
} 

def createFoo(Map params) { 
    return new Foo(params) 
} 

println createFoo(defaults) 
println createFoo(defaults << [age:21]) 
println createFoo(defaults << [ name:'Jane', address:'Low Street']) 

NOTA: operazione leftShift (< <) modifica la mappa originale, quindi nell'esempio di età superiore a 21 sarà l'ultima chiamata al metodo pure. Nel mio caso, questo non è un problema dato che la mappa di default può essere creata ogni volta di nuovo nel metodo di installazione.

+0

Non farlo. 'defaults' mantiene lo stato in questo caso. Rendilo locale. Vedi il mio aggiornamento. – dmahapatro

+0

L'ho capito, quindi la nota nel mio aggiornamento. Ad ogni modo, usare una mappa locale delle funzioni per i valori predefiniti è un approccio molto migliore. Grazie per il consiglio. – kaskelotti

risposta

22

Groovy lo fa per impostazione predefinita (costruttore di mappe). Non avresti bisogno di un metodo di fabbrica. Ecco un esempio

import groovy.transform.ToString 

@ToString(includeFields = true, includeNames = true) 
class Foo{ 
    String name = "Default Name" 
    int age = 25 
    String address = "Default Address" 
} 

println new Foo() 
println new Foo(name: "John Doe") 
println new Foo(name: "Max Payne", age: 30) 
println new Foo(name: "John Miller", age: 40, address: "Omaha Beach") 

//Prints 
Foo(name:Default Name, age:25, address:Default Address) 
Foo(name:John Doe, age:25, address:Default Address) 
Foo(name:Max Payne, age:30, address:Default Address) 
Foo(name:John Miller, age:40, address:Omaha Beach) 

UPDATE
@ astrologia del codelark :). Nel caso in cui la classe non sia accessibile per impostare valori predefiniti, è possibile fare come

@ToString(includeFields = true, includeNames = true) 
class Bar{ 
    String name 
    int age 
    String address 
} 

def createBar(Map map = [:]){ 
    def defaultMap = [name:'John Doe',age:51,address:'High Street 11'] 
    new Bar(defaultMap << map) 
} 

println createBar() 
println createBar(name: "Ethan Hunt") 
println createBar(name: "Max Payne", age: 30) 
println createBar(name: "John Miller", age: 40, address: "Omaha Beach") 


//Prints 
Bar(name:John Doe, age:51, address:High Street 11) 
Bar(name:Ethan Hunt, age:51, address:High Street 11) 
Bar(name:Max Payne, age:30, address:High Street 11) 
Bar(name:John Miller, age:40, address:Omaha Beach) 
+3

e se per qualche motivo non si desidera utilizzare il costruttore di mappe, è possibile creare la funzione come sopra ma con un singolo parametro di mappa e ottenere la stessa funzione. – codelark

+1

Ho aggiornato la mia domanda con questi dettagli, ma li aggiungerò anche qui per voi. Il metodo è a scopo di test, quindi non posso toccare i valori predefiniti della classe Foo effettiva. – kaskelotti