Посмотрел Grails. С точки зрения «джависта» — «полный угар»: методы, котрые являются методами экземпляра у CriteriaBuilder и EntityManager, перобразованы в статические методы у сущностей. Как будто все сущности наследуют от одного предка. Ну еще и прикопипастнуты методы (или пригенерированы по шаблону), вызывающие методы предка с доп.аргументом — классом:
public class Person extends DBExternalizableBase{
...
public static Person get(int id){
return DBExternalizableBase.<Person>get(Person.class, id);
}
...
}
Вкурил дальше — так и есть, делается через препроцессор. От препроцессора в самой Java отказались сразу. Посмотрел дальше — никакой переносимости кода между библиотеками или между контейнерами даже и не подразумевается, что для программирования на самой Java моветон вдвойне.
Согласен. Если для некоего частого поведения требуется паттерн, значит, в языке не хватает идиом или библиотечных функций/макросов. Паттерны — это костыли для хоть какого-то лечения этой нехватки.
Кем считаются? Не мной точно. Паттерны — это по определению «костыли», раз можно не только «так», а ещё и «не так», раз можно, например, не только «собирать мусор», а ещё и «не собирать мусор». Лучший паттерн — это элемент синтаксиса языка, как оператор вызова функции или оператор цикла или интерфейс в Java. Второй — это системная библиотека, подпрограмма или макрос, которые вынуждают его использовать, типа ситуации с ActionListener-ами в Java. Третий — несистемная библиотека, подпрограмма или макрос, которые вынуждают его использовать.
Реализация высокоуровневых черт в низкоуровневыз языках. В 1950-е годы, ещё до изобретения стека и немного после него, на ассемблере некоторых машин вызов подпрограммы тоже был «шаблоном дизайна».
Я прежде всего имел в виду пригодность для полуавтоматического рефакторинга средствами IDE, что в разы увеличивает объём кода, которым можно управлять в одиночку.
Для domain objects — да: «проксируемые structs» и сервис-объекты. Но, кроме «доменщины», описывающей реальный мир, существуют библиотеки подпрограмм: в них ОО-парадигма служит способом более компактной, удобной и читабельной организации кода. Об этом я написал только последний абзац;-)
Если метод можно прицепить к объекту в runtime-е, а не на этапе проектирования, то это уже не tight coupling. Правда, в нагрузку это ещё и не рефакторится.
Средствами контейнера наинженерить класс-наследник-обёртку, который будет транслировать вызовы на сам объект и возвращать полкченный результат и, кроме, делать что-то до/после(/вместо) получения результата от самого проксируемого объекта (в частности, логгирование или управление транзакциями).
С вызовами функций такая фишка проходит, с обращением к полям — нет.
«убрать любой ценой» — это ценой провала проекта, потери всей своей доли рынка и штрафных санкций за неустойку от того, что с новой версии продукт стал работоспособен на 0%, — тоже?
IRL новорождённых идентифицируют по матери — сразу после рождения прикрепляют соотв. бирку на руку, по крайней мере в 2000 так было.
Свидетель и анонимный донор — это не люди, а роли, делать их потомками класса Person сегодня рассматривается как bad design. Надо не наследовать, а агрегировать.
Для новорождённых тоже можно сделать отдельный класс, не наследуемый от Person.
Вкурил дальше — так и есть, делается через препроцессор. От препроцессора в самой Java отказались сразу. Посмотрел дальше — никакой переносимости кода между библиотеками или между контейнерами даже и не подразумевается, что для программирования на самой Java моветон вдвойне.
Уточню свой ответ — это сейчас в основном реализация черт функциональных языков в языках, в которых функция не является «объектом первого класса».
недавно нашёл — norvig.com/design-patterns/ или www.google.com/search?q=peter+norvig+design+patterns+in+dynamic+languages
А что вы подозревали, что я имею в виду?
Инкапсуляция вынуждает использовать методы. Потом эти методы можно переопределить и(ли) обынтерфейсить.
Важно знать типы на этапе компиляции, это делает язык пригодным для «дешёвого» и интенсивного рефакторинга.
С вызовами функций такая фишка проходит, с обращением к полям — нет.
Свидетель и анонимный донор — это не люди, а роли, делать их потомками класса Person сегодня рассматривается как bad design. Надо не наследовать, а агрегировать.
Для новорождённых тоже можно сделать отдельный класс, не наследуемый от Person.