Каковы на самом деле методы Gpath и Chaining? - PullRequest
0 голосов
/ 04 февраля 2012

Я запутался с этими двумя строками кода:

this.class.methods.name

Это называется Gpath (я прав?). Теперь рассмотрим этот код:

count = 0
def a = [1,2,3,4,5,5,51,2]
a.findAll { it == 5 }​.each { count ++ }
println count

Строка:

a.findAll { it == 5 }​.each { count ++ }

называется как метод цепочки или Gpath?

Буквально, я был поражен этими двумя значениями. Было бы хорошо, если бы кто-то объяснил разницу между этими двумя.

Заранее спасибо.

1016 *

Ответы [ 2 ]

3 голосов
/ 05 февраля 2012

Я не уверен, правильно ли я понял вопрос.

Как я вижу, в обоих примерах вы используете цепочку методов просто потому, что вы вызываете метод в объекте, который возвращается другим методом. Но, как Артуро упоминает , некоторые люди путают цепочку методов и плавные интерфейсы . Свободный интерфейс действительно очень удобен, если вы хотите объединить методы.

В Groovy, однако, вы можете вместо того, чтобы самостоятельно кодировать свободный интерфейс, использовать метод with в любом объекте. Например, используя те же классы Person и Address, которые были определены Артуро, вы можете сделать:

def person = new Person()
person.with {
    name = 'John'
    age = 25
    address = new Address('Boulevard St')
}
assert person.name == 'John' &&
       person.age == 25 &&
       person.address.name == 'Boulevard St'

Теперь, GPath , как я понимаю, это просто способ доступа к свойствам объекта. Например, если у вас есть класс:

class Foo {
    def bar
}

Механизм GPath в Groovy позволяет выполнять следующие действия:

def foo = new Foo(bar: 42)
assert foo.bar == 42

Вместо того, чтобы обращаться к свойству bar с его геттером, как foo.getBar(). Ничего особенного. Но другие классы в Groovy также имеют магию GPath, и есть вещи, которые становятся более интересными. Например, списки позволяют обращаться к свойствам их элементов так же, как к обычным свойствам:

def foos = (1..5).collect { new Foo(bar: it) } // Five Foos.
assert foos.bar == [1, 2, 3, 4, 5]

Как вы можете видеть, доступ к свойству bar в списке объектов, которые имеют этого свойства, приведет к появлению списка со значениями этого свойства для каждого объекта в списке. Но если вы обращаетесь к свойству, которого нет в элементах списка, например, foos.baz, будет выдано исключение MissingPropertyException.

Это именно то, что происходит в:

this.class.methods.name

Я, однако, считаю, что это поведение слишком волшебно, на мой вкус (если только вы не анализируете XML, в этом случае все в порядке). Обратите внимание, что если коллекция, возвращаемая методом methods, будет какой-то странной коллекцией, имеющей свойство name, methods.name приведет к этому имени вместо имен каждого метода в коллекции. В этих случаях я предпочитаю использовать более явную версию (IMO):

this.class.methods*.name

, который даст вам тот же результат, но это всего лишь синтаксический сахар для:

this.class.methods.collect { it.name }

... и давайте сделаем намерение выражения более понятным (т. Е. «Я хочу, чтобы имена каждого метода были в methods»).


Наконец, и это совершенно не по теме, код:

count = 0
def a = [1,2,3,4,5,5,51,2]
a.findAll { it == 5 }​.each { count ++ }
println count

можно переписать как:

def a = [1,2,3,4,5,5,51,2]
def count = a.count { it == 5 }
println count

:)

2 голосов
/ 05 февраля 2012

Я думаю, что ваш код является примером цепочки методов .

GPath - это язык выражения пути, интегрированный в Groovy, который позволяет перемещаться в XML или POJO. Вы можете выполнять вложенный доступ к свойствам в объектах.

Цепочка методов - это метод вызова нескольких вызовов методов в объектно-ориентированных языках программирования. Каждый метод возвращает объект (возможно, сам текущий объект), позволяя объединить вызовы в один оператор.

Я собираюсь использовать пример с TupleConstructor , чтобы помочь в создании объекта.

import groovy.transform.TupleConstructor

@TupleConstructor
class Address {
    String name
}

@TupleConstructor
class Person {
    String name
    Integer age
    Address address
}

def person = new Person('John', 25, new Address('Boulevard St'))


Хорошо, вы правы, этот доступ называется GPath:

assert person.address.name == 'Boulevard St'

Доступ получателя может быть назван цепочкой метода:

assert person.getAddress().getName() == 'Boulevard St'


Но что произойдет, если я смогу сделать что-то вроде этого:

person.setName('Louise')
      .setAge(40)
      .setAddress(new Address('Main St'))

Мне нужно создать свободный API, способ цепочки методов, идея состоит в том, чтобы позволить методам возвращать this вместо void.

@TupleConstructor
class Person {
    String name
    Integer age
    Address address

    def setName(name) {
        this.name = name
        return this
    }

    def setAge(age) {
        this.age = age
        return this
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...