Видел интересный на днях, возможно, неделя, на блоге, который я не могу помнить. В основном я не могу приписать себе это, но я думал, что это могло бы иметь некоторое полезное приложение.
Говорят, что Вы хотели, чтобы абстрактный класс был замечен другим блоком, но Вы не хотите, чтобы кто-то был в состоянии наследоваться ему. Изолированный не будет работать, потому что это абстрактно по причине, другие классы в том блоке действительно наследовались ему. Частный не будет работать, потому что Вы могли бы хотеть объявить Родительский класс где-нибудь в другом блоке.
namespace Base.Assembly { public abstract class Parent { internal abstract void SomeMethod(); } //This works just fine since it's in the same assembly. public class ChildWithin : Parent { internal override void SomeMethod() { } } } namespace Another.Assembly { //Kaboom, because you can't override an internal method public class ChildOutside : Parent { } public class Test { //Just fine private Parent _parent; public Test() { //Still fine _parent = new ChildWithin(); } } }
, Как Вы видите, это эффективно позволяет кому-то использовать Родительский класс не имея возможности для наследования.
Следующий код Groovy выведет «Я фильтрую!»:
class SecurityFilters {
def filters = {
myFilter(controller:'*', action:'*') { // What are those weird colons??
print "I'm filtering!"
// Code that does the filtering goes here
}
}
}
class FilterDelegate {
def methodMissing(String methodName, args) {
// methodName == myFilter
// args[0] == [controller:*, action:*]
// args[1] == {print "I'm filtering!"}
args[1].call()
}
}
def sf = new SecurityFilters()
def filtersClosure = sf.filters
filtersClosure.delegate = new FilterDelegate()
filtersClosure.call()
В этом примере filter - это замыкание, которое вызывает метод с именем myFilter и передает карту и закрытие. Вы можете думать о myFilter как о:
myFilter([controller:'*', action:'*'], closure)
Карта может содержать такие ключи, как controller, action или uri. Подстановочный знак (*) используется, когда Grails пытается сопоставить URI из HTTP-запроса, когда он пытается определить, какое закрытие вызывать.
Насколько я понимаю, Grails обрабатывает фильтры, это то, что используется класс загрузчика делегата. Класс загрузчика предоставляет метод methodMissing и создает FilterConfig для каждого вызова метода внутри закрытия фильтров. Когда делается HTTP-запрос, Grails просматривает все объекты FilterConfig и пытается найти подходящую область (ищет на карте контроллер, action или uri и использует регулярные выражения для сопоставления с подстановочными знаками). Если он находит совпадение, он вызывает закрытие, которое было передано в метод в классе Filter.
Вы не можете легко вызвать фильтры вне Grails, потому что они зависят от большого количества сантехники, которая не будет настроена. Строка
myFilter (controller: '', action: '')
- это определение метода, которое принимает два аргумента: контроллер и шаблон действия. * означает применить этот фильтр к любому объекту исходящего типа. Например, если мы хотим убедиться, что пользователи не могут ничего создавать, если они не авторизованы, мы бы использовали следующий фильтр.
controller: '*', action: 'create'
Это будет означать, что каждый раз, когда вызывается действие create, код, хранящийся в теле этой функции, будет выполняться, но для list, show или edit никакой фильтр не будет выполняться . Если вам действительно нужны подробности, вы всегда можете скачать исходный код grails.
edit:
Код компилируется, поскольку это функция, определенная в фильтре.