Как отделить интерфейс от реализации в сервисах Grails? - PullRequest
15 голосов
/ 02 февраля 2011

Мне было интересно, возможно ли создать сервисный интерфейс на Grails, и я не могу найти правильный способ сделать это. Это объяснение не является удовлетворительным, поскольку кажется, что он смешивает Java и Groovy:

http://www.grails.org/doc/latest/guide/8.%20The%20Service%20Layer.html

Мне кажется, что это плохой дизайн фреймворка, учитывая, что механизм интерфейса является одной из лучших функций Java (и большинства языков OO).

Есть идеи прояснить этот вопрос?

Спасибо! Mulone

Ответы [ 4 ]

18 голосов
/ 21 февраля 2012

У вас может быть интерфейс, но на самом деле он вам не нужен. Если я вас правильно понимаю, вы хотели бы иметь две реализации службы и иметь возможность выбирать, какую из них использовать.

Просто реализуйте две службы, названные, например, MyService1 и MyService2, тогда в grails-app/conf/spring/resource.groovy вы можете указать:

beans = {
    ... 
    // syntax is beanId(implementingClassName) { properties }
    myService(MyService1)
    ...
}

или даже:

beans = {
    ...
    if (someConfigurationOption) {
        myService(MyService1)
    } else {
        myService(MyService2)
    }
}

Вот как вы указываете Spring, какой сервис на самом деле внедрить для myService. Теперь вы сможете использовать myService как:

public MyController {
    def myService
    ...
}

и Spring автоматически подключит правильную реализацию. Это позволяет вам сконфигурировать, какую реализацию сервиса использовать, например, на основе какой-либо конфигурации.

5 голосов
/ 02 февраля 2011
  • Определить интерфейс службы в классе com.mycompany.mypackage.MyInterface.groovy сохранено under src/groovy
  • Определить реализацию службы, сохраненную в grails-app/services

    class MyService implements MyInterface {
        // service implementation goes here
    }
    
1 голос
/ 02 февраля 2011

Это не недостаток дизайна. Groovy отличается от java тем, что это динамический язык, который использует 'duck-typing'. В groovy интересно то, что есть и интерфейсы. Поэтому, если вы последуете совету @ don, вы можете убедиться, что ваш сервис соответствует интерфейсу, но способ, которым вы выполняете DI с помощью grails, - просто указать реализацию сервиса. то есть вы не получаете проверку времени компиляции , где вы используете реализацию сервиса, как вы делаете в java.

Обратите внимание, что здесь нет жесткой связи. Связь подразумевает, что что-то связано с типом. Но с помощью свободной системы печати Groovy, типы по существу являются динамическими существами. Таким образом, в Java, если вы объявите тип как конкретную реализацию, код может не скомпилироваться, если вы измените тип позже. В groovy код всегда будет компилироваться, если вы используете 'def' ... (я думаю, это правильно)

0 голосов
/ 18 июня 2016

Лучшее решение, которое я нашел для этого, это использовать Псевдонимы бобов Spring . В основном вам нужно:

1) Создать интерфейс в src / groovy (MyService.groovy)

2) Внедряйте свои услуги там, где они вам нужны:

class MyController {
    MyService myService
}

3) Создайте свои обычные службы, реализующие этот интерфейс (ImplOneService.groovy, ImplTwoService.groovy)

4) Добавьте запись в resources.groovy, где вы определяете, какую реализацию использовать (в конце концов, тестирование для среды или что-то еще, что вам нужно):

beans = {
    if (...development, useFTP, etc...) {
        springConfig.addAlias 'myService', 'ImplOneService'
    } else {
        springConfig.addAlias 'myService', 'ImplTwoService'
    }
}

Полные источники здесь

Мои комментарии: Использование интерфейсов в groovy действительно кажется чем-то вроде «я хочу придерживаться некоторых java-вещей, с которыми мне удобнее». В этом случае строгая типизация. Но это отличная фраза: «Не беспокойтесь, вы можете придерживаться Java, если хотите».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...