2013-08-01 1 views
15

Возможно ли иметь именованные параметры со значениями по умолчанию в groovy? Мой план состоит в том, чтобы создать своего рода объектную фабрику, которую можно вызвать без каких-либо аргументов, чтобы получить объект со значениями по умолчанию. Кроме того, мне понадобится функциональность, чтобы явно установить любой из параметров для объекта. Я считаю, что это возможно с помощью аргументов ключевого слова Python, например.именованные параметры со значениями по умолчанию в groovy

Код я пытаюсь с прямо сейчас что-то вроде ниже

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

Реальное приложение, которое я работаю над будет иметь гораздо больше параметров и, таким образом, намного больше комбинаций необходимо.

Благодаря

UPDATE:

Фабричный метод я планирую для целей тестирования. Невозможно по-настоящему коснуться фактического класса Foo и, особенно, его значения по умолчанию.

@dmahapatro и @codelarks answere ниже имели хорошую возможность использовать карту как параметр, который дал мне представление о возможном решении. Я мог бы создать карту с желаемыми значениями по умолчанию и переопределить необходимые значения и передать это фабричному методу. Это, вероятно, сделает эту работу, и я пойду с этим, если не получу намек на лучший подход.

Мой текущий подход ниже

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

Примечание: операции leftShift (< <) изменяет исходную карту, поэтому в приведенном выше примере возраста будет в последнем вызове метода 21 а. В моем случае это не проблема, так как карта по умолчанию может быть создана свежестью каждый раз в методе настройки.

+0

Не делайте этого. 'defaults' поддерживает состояние в этом случае. Сделайте его локальным. См. Мое обновление. – dmahapatro

+0

Я понял, что, следовательно, заметка в моем обновлении. Во всяком случае, использование локальной локальной карты функций по умолчанию является гораздо лучшим подходом. Спасибо за совет. – kaskelotti

ответ

22

Groovy делает это по умолчанию (конструктор карты). Вам не нужен фабричный метод. Вот пример

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 в :). Если класс не доступен для установки значений по умолчанию, вы можете сделать это как

@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

, и если по какой-то причине вы не хотите использовать конструктор карты, вы можете создать функцию, как указано выше, но с одним параметром карты и выполнить одно и то же. – codelark

+1

Я обновил свой вопрос с этими подробностями, но я также добавлю их сюда для вас. Метод предназначен для тестирования, поэтому я не могу коснуться значений по умолчанию для фактического класса Foo. – kaskelotti