2013-08-01 10 views
15

Ist es möglich, benannte Parameter mit Standardwerten in groovy haben? Mein Plan ist es, eine Art Objektfabrik zu erstellen, die ohne Argumente aufgerufen werden kann, um ein Objekt mit Standardwerten zu erhalten. Außerdem würde ich die Funktionalität benötigen, um alle Parameter für das Objekt explizit festzulegen. Ich glaube, dass dies zum Beispiel mit Python-Schlüsselwortargumenten möglich ist.benannte Parameter mit Standardwerten in groovy

Der Code, den ich mit jetzt bin versucht, ist so etwas wie unten

// 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 

Die eigentliche Anwendung, die ich arbeite wird viel mehr von Parametern und damit viel mehr Kombinationen benötigt.

Dank

UPDATE:

Die Factory-Methode I Planung bin für Testzwecke ist. Kann die tatsächliche Foo-Klasse nicht wirklich berühren und vor allem nicht ihre Standardwerte.

@dmahapatro und @codelarks Antwort unten hatte einen guten Punkt in der Verwendung einer Karte als ein Parameter, der mir eine Idee einer möglichen Lösung gab. Ich könnte eine Karte mit den gewünschten Standardwerten erstellen und die erforderlichen Werte überschreiben und diese an die Factory-Methode übergeben. Das wird wahrscheinlich den Job machen, und ich werde damit fortfahren, wenn ich nicht einen Hinweis auf einen besseren Ansatz bekomme.

Mein aktueller Ansatz unter

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']) 

HINWEIS: Leftshift-Operation (< <) modifiziert die die ursprüngliche Karte, so in dem obigen Beispiel Alter wird auch 21 in dem letzten Methodenaufruf sein. In meinem Fall ist das kein Problem, da die Standardkarte jedes Mal in der Setup-Methode neu erstellt werden kann.

+0

Tun Sie das nicht. 'defaults' behält in diesem Fall den Zustand bei. Mach es lokal. Siehe mein Update. – dmahapatro

+0

Ich habe das erkannt, daher der Hinweis in meinem Update. Wie auch immer, die Verwendung einer lokalen Karte für die Standardeinstellungen ist ein weitaus besserer Ansatz. Danke für den Tipp. – kaskelotti

Antwort

22

Groovy macht das für Sie standardmäßig (map constructor). Sie würden keine Fabrikmethode benötigen. Hier ist ein Beispiel

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
@ codelark der Astrologie :). Wenn auf die Klasse nicht zugegriffen werden kann, um Standardwerte festzulegen, können Sie folgendermaßen vorgehen:

@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

und wenn Sie aus irgendeinem Grund den Map-Konstruktor nicht verwenden möchten, können Sie die Funktion wie oben, aber mit einem einzigen map-Parameter erstellen und dasselbe ausführen. – codelark

+1

Ich habe meine Frage mit diesen Details aktualisiert, aber ich werde sie auch hier für Sie hinzufügen. Die Methode dient Testzwecken, daher kann ich die Standardwerte der tatsächlichen Foo-Klasse nicht berühren. – kaskelotti